Copyright: Copyright 1997-98 Elevate Software


Contents
DBISAM Database System

Shipping Release 1.05

Welcome to the DBISAM Database System for Delphi 1.02 / 2.01 / 3.0x / 4.0x. Be sure to review our links regarding bug reports and enhancement requests so that if the need arises you'll have everything handy to report any information regarding a bug or something that needs improving.

Please note, this help file assumes at least a cursory understanding of the data access components (TDatabase, TDataSet, TTable, TBatchMove, TQuery, TStoredProc, TField, etc) that ship with Delphi and their usage. Please refer to the Delphi online help files or printed manuals for more information about using the data access components. Because a large portion of the DBISAM data access components are either the original Delphi components themselves or very close duplicates this help file will not spend a large amount of time duplicating the documentation already present in Delphi.  Instead, the majority of this help file is geared toward explaining the differences between the BDE and DBISAM and how that affects the usage of the data access components.

Please make sure that you take a moment to go through the Before You Begin topic before using DBISAM with any database project in Delphi.

 Before You Begin

 Overview of Database System

 Reporting Bugs and Enhancement Reports

 Provided System Utilities

 Overview of Delphi 1 Support

 Overview of Delphi 2 Support

 Overview of Delphi 3 Support

 Overview of Delphi 4 Support

 Error Messages and Error Handling

 System Capacities

Did we miss anything that you were looking for ?  If so, please let us know so that we can add it to the online help and get it out to other users.

Delphi, BDE, Database Desktop, dBase, and Paradox are trademarks of Inprise Corporation (formerly Borland International)

Windows, Windows 95, Windows NT, Microsoft Exhange, FoxPro and Access are trademarks of Microsoft Corporation

DBISAM is a trademark of Elevate Software


Reporting Bugs and Enhancement Requests
Reporting Bugs and Enhancement Reports

In order to provide the fastest turnaround time on new bug reports / enhancement requests (we call them incidents as a general classification) and to assist you in locating the necessary information about existing incident reports we have provided an application just for this purpose called the DBISAM Customer Support System.  It allows you to:

 	Easily review existing incident reports

Search on the contents of incident reports

Print incident reports

Add a new incident report

Automatically e-mail (via Internet mail) any new incident reports to us directly at Elevate Software

Download new incident report databases from our web site as needed

Quickly and easily import new incident databases into your local application

 Customer Support System


Provided System Utilities

Included with the DBISAM Database System are a few utilities that hopefully will enhance your productivity in getting started.  These utilities include:

 Database System Utility (DBSYS.EXE)

The Database System Utility is designed to offer similar functionality to those coming from the BDE and the Database Desktop that ship with all versions of Delphi.  With this utility you can view data files, update data files, restructure data files, import and export ascii files, and much more.  For more information just click on the appropriate link above.

 BDE Database Transfer Utility (BDETRAN.EXE)

The BDE Database Transfer Utility is designed to allow you to quickly and easily get an existing system using Paradox or dBase/Foxpro data files moved over to the DBISAM data file format.  With this utility you can simply select the data files you want transferred and it will take care of creating the new DBISAM data files and copying over all data in your existing data files.  All of this is done without making any changes (the files are opened read-only) at all to your existing data files so you can also convert an existing system with little to no risk involved.  For more information just click on the appropriate link above.


Overview of Delphi 1 Support

DBISAM includes replacement .DCUs for Delphi 1.02 only.  Delphi 1.02 can be ordered as an upgrade CD-ROM from Borland or is available on the Delphi 2.x, Delphi 3.0x, and Delphi 4.0x CD-ROMs.  The two .DCUs replaced are:

 	DB.DCU  (the base TSession, TDatabase, TDataSet, TDBDataSet, and TField components)

DBTABLES.DCU  (the TTable, TBatchMove, TQuery, TStoredProc, and TField descendant components)

DBISAM also includes a .DCU for a TTable descendant called TDBISAMTable that provides additional properties, methods, and events to bring the Delphi 1.02 support for DBISAM closer to what is currently provided in Delphi 2.01 and 3.x:

DBISAMTB.DCU  (the descendant TDBISAMTable component)

DBISAMCN.DCU  (constants unit used by the descendant TDBISAMTable component)

 Installation

 Differences Between Delphi/BDE and Delphi/DBISAM


Overview of Database System

This topic is devoted to giving you an understanding of how the DBISAM Database System works so that you may better be able to take advantage of it's abilities and avoid it's pitfalls also.  First the data files, then the index files, then the blob files, and lastly the database engine and data access components will be discussed.

 Data Files

 Index Files

 Blob Files

 Low-Level Database Objects

 Data Access Components


Severe Corruption
An example of severe corruption would be when a system device driver is not behaving as expected and is causing data to be written to disk improperly.  This type of corruption can sometimes go on for quite a while before it is actually detected.  Please note also that this type of corruption is extremely rare and does not include the more frequent "user turned off the power to the PC" type of corruption, which usually only causes minor, easily repairable damage, if any damage at all.


Index Pages
A page is one contiguous 1024-byte area on disk. Data is normally stored in even 512-byte sizes so that disk access will be optimized.  DBISAM uses pages for index files only.


Blob Blocks
Blob blocks are the same as index pages except that they are x (determined by user) number of bytes in length instead of 1024 bytes in length.  The naming convention is strictly arbitrary and used to reduce confusion between the two.


Delphi 1 Installation

To install the replacement DCUs for DBISAM into the component library in Delphi 1.02, please perform the following steps in Delphi:

1	Select the Options option from the main menu

2	Select the Install Components option from the Options menu

3	At the BEGINNING of the Search Path edit control, type the following:

 <Install Directory>\DELPHI1;

This will place the path where you installed the Delphi 1.02 components before the normal BDE-based Delphi data access components and will enable the DBISAM Database System for use under Delphi 1.02.  Be sure to include the semicolon between the newly inserted path and the existing library search path and be sure not to overwrite any of the existing library search path.

4	Select the OK button to proceed with rebuilding the component library using the DBISAM data access components

If you have any problems with this procedure please be sure to contact technical support for help.

To install the TDBISAMTable descendant component DCU for DBISAM into the component library in Delphi 1.02, please perform the following steps in Delphi:

1	Select the Options option from the main menu

2	Select the Install Components option from the Options menu

3	Select the Add button, which will bring forward the Add Module dialog

4	Select the Browse button on the Add Module dialog, and change directories to the Delphi1 subdirectory under the main directory where DBISAM was installed

5	Double-click on the DBISAMTB.DCU file

6	Select the OK button to proceed with rebuilding the component library with the newly added TDBISAMTable component


Delphi 1 Differences
Differences Between Delphi/BDE and Delphi/DBISAM in Delphi 1

There are several things that are different between the original Delphi .DCUs and the replacement .DCUs provided by DBISAM.  These differences are documented here by component:

 TSession Component

 TDatabase Component

 TQuery Component

 TStoredProc Component

 TBatchMove Component

 TTable Component

 TDBISAMTable Component


Delphi 1 TSession Component
Differences Between Delphi/BDE and Delphi/DBISAM in Delphi 1

TSession Component

The following is a listing of the properties and methods in the TSession component that have changed in behavior with DBISAM and the notes about the changes:

Property, Method, or Event	Notes

Locale Property	DBISAM does not currently provide for international support so the Locale property is ignored.

NetFileDir Property

PrivateDir Properties 	Both of these properties are ignored in the DBISAM TSession component.  The NetFileDir and PrivateDir properties are based on concepts specifically related to using Paradox data files and the BDE.

GetAliasNames Method

GetAliasParams Method

GetStoredProcNames Method	These methods are ignored in the DBISAM TSession component.  DBISAM does not support either alias names or stored procedures.

GetDriverNames Method

GetDriverParams Method

GetTableNames Method	These methods all still work as expected, the one difference being that the GetDriverNames method only returns one driver name - "DBISAM".


Delphi 1 TDatabase Component
Differences Between Delphi/BDE and Delphi/DBISAM in Delphi 1

TDatabase Component

The following is a listing of the properties and methods in the TDatabase component that have changed in behavior with DBISAM and the notes about the changes:

Property, Method, or Event	Notes

Locale Property	DBISAM does not currently provide for international support so the Locale property is ignored.

TransIsolation Property

StartTransaction Method

Commit Method

Rollback Method	The BDE provided with Delphi 1.02 does not allow for transactions on local databases such as Paradox or dBase. DBISAM does allow for transactions, but only one per database can be active at any given time.  When you start a transaction using the StartTransaction method of the TDatabase component, any TTable components that are connected to this TDatabase component are now involved in the current transaction.  Any changes made to these TTable components will be logged in the appropriate transaction log and will be committed or rolled back as a group under the current transaction. You must be very careful when using multiple TDatabase components with active transactions on the same TTable components, since either rolling back any changes or committing any changes could cause great confusion as to how the data files actually got into their current state.  It is normally only a good idea to have one active transaction on any given TTable component and to make sure that your TTable components are not accidentally attached to different databases.  Also, if you do not explicitly use a TDatabase component and instead rely on the temporary TDatabase component ( this TDatabase component is created for TTable components that use a path name for the DatabaseName property), be sure to remember that all TTable components in the current application will be attached to the same temporary database.

The transaction isolation level property of the TDatabase component doesn't need to be set to anything in particular to allow for proper usage of the transactions in DBISAM since this property is ignored.

Finally, the default Delphi TDatabase component does not ensure that the TTable components involved in the current transaction are all in the dsBrowse state, or, in other words, not editing, adding, filtering, or searching, when it commits or rolls back an existing transaction.  In the DBISAM replacement TDatabase component all TTable components are forced into browse mode before any transaction is rolled back or committed.  This means that any records being edited, added, or searched on will be posted using the standard Post method of TTable component if the transaction is being committed and cancelled if the transaction is being rolled back.

Params Property	The only parameters necessary in the Params property for the DBISAM TDatabase component is the PATH parameter.  It still requires the same syntax as the default Delphi TDatabase component:

PATH=X:\MYDIR

AliasName Property	The AliasName property will always be blank since DBISAM does not support alias names.  You must always provide a DatabaseName and specify the DriverName (see next issue).

DriverName Property	The only driver name available under the DriverName property for the DBISAM TDatabase component is the "DBISAM" driver.  You still need to select the driver name, it will not be selected automatically.

OnLogin Event	User names and logging in are not necessary when using DBISAM, and so this functionality has been disabled.  The OnLogin event will never be called and any USER NAME parameter in the Params property of the TDatabase component will be ignored.


Delphi 1 TQuery Component
Differences Between Delphi/BDE and Delphi/DBISAM in Delphi 1

TQuery Component

DBISAM does not support SQL queries so all functionality related to the TQuery component has been disabled.  DO NOT USE THIS COMPONENT WITH DBISAM.


Delphi 1 TStoredProc Component
Differences Between Delphi/BDE and Delphi/DBISAM in Delphi 1

TStoredProc Component

DBISAM does not support stored procedures so all functionality related to the TStoredProc component has been disabled.  DO NOT USE THIS COMPONENT WITH DBISAM.


Delphi 1 TBatchMove Component
Differences Between Delphi/BDE and Delphi/DBISAM in Delphi 1

TBatchMove Component

DBISAM does not currently support batch moves so all functionality related to the TBatchMove component has been disabled.  DO NOT USE THIS COMPONENT WITH DBISAM.


Delphi 1 TTable Component
Differences Between Delphi/BDE and Delphi/DBISAM in Delphi 1

TTable Component

The following is a listing of the properties and methods in the TTable component that have changed in behavior with DBISAM and the notes about the changes:

Property, Method, or Event	Notes

Locale Property

DBLocale Property	DBISAM does not currently provide for international support so the Locale and DBLocale properties are ignored.

KeyExclusive Property	DBISAM does not support exclusive keys in ranges and searches so the KeyExclusive property is ignored.

TableType Property	The TableType property is set to ttDefault by default and cannot be changed since the default table type for DBISAM is DBISAM tables.  Paradox and dBase access via the BDE concurrently with DBISAM is not supported.

LockTable Method

UnlockTable Method	DBISAM only supports locking an entire to prevent other users from writing to the table, not reading the table, so the LockTable and UnlockTable methods ignore the parameter indicating the type of lock (ltRead or ltWrite).

BatchMove Method	Batch moves (and the TBatchMove component) are not currently supported in DBISAM so the BatchMove method is ignored.

CreateTable Method

AddIndex Method	There are several differences between how creating tables using the CreateTable method is handled in the default Delphi TTable component and the BDE versus how it is handled in the DBISAM TTable component.

When adding field definitions for blob fields such as memos or graphics, Paradox and the BDE allow you to specify a field size that indicates how much of the current blob field contents should be stored directly in the data record.  DBISAM does not support this feature, so the field size for blob fields should always be set to 0 as indicated in the following example:

with Table1 do

  begin

  Active := False;

  DatabaseName := 'Delphi_Demos';

  TableName := 'CustInfo';

  TableType := ttDefault;

  with FieldDefs do

    begin

    Clear;

    Add('Field1', ftInteger, 0, True);

    Add('Field2', ftMemo, 0, False);  { <--- With DBISAM tables the field size must be 0 for blob fields }

    end;

  with IndexDefs do

    begin

    Clear;

    Add('','Field1',[ixPrimary]);

    end;

  CreateTable;

  end;

The following TField components are considered blob fields:

 	TMemoField

TGraphicField

TBlobField

There are some options used when adding index definitions used in the CreateTable method, and also when using the AddIndex method, that are handled differently than the default Delphi TTable component.

Option	Notes

ixUnique 	This option is used with the BDE and Paradox and dBase tables to specify a unique index. In DBISAM the unique option behaves in the same manner as Paradox.  The unique option enforces that duplicate index keys for the specified index will not be allowed in the data file.  The uniqueness of index keys are enforced automatically for primary indexes (defined using the ixPrimary option alone).

ixCaseInsensitive	DBISAM does support case-insensitive indexes and the ixCaseInsensitive option for both primary and secondary indexes.

ixNonMaintained	This option is used with the BDE and Paradox tables to specify indexes that are not maintained automatically by the BDE when updating the table.  DBISAM does not support this feature so this option is ignored.

ixDescending	DBISAM does support descending indexes and the ixDescending option for both primary and secondary indexes.  An example of using the CreateTable to create a table using both primary and secondary indexes, ascending and descending is as follows:

with Table1 do

  begin

  Active := False;

  DatabaseName := 'Delphi_Demos';

  TableName := 'CustInfo';

  TableType := ttDefault;

  with FieldDefs do

    begin

    Clear;

    Add('Field1', ftInteger, 0, True);

    Add('Field2', ftString, 20, False);

    Add('Field3', ftDate, 0, False);

    end;

  with IndexDefs do

    begin

    Clear;

    Add('', 'Field1', [ixPrimary]); {<-- This is an ascending primary index, you could add the ixDescending option if you wanted to make this primary index descending }

    Add('Field2Index', 'Field2', []);  {<-- This index definition is an ascending secondary index }

    Add('Field3Index', 'Field3', [ixDescending]);  {<-- This index definition is a descending secondary index }

    end;

  CreateTable;

  end;


Database System Overview Data Files
Overview of Database System

Data Files

The data files in DBISAM contain a variable-length header containing field information which is followed by x number of fixed-length data records where x is the number of records in the data file.  The fixed length data records can be wasteful on space compared to variable-length data records but, due to the nature of being fixed in length, are much more robust when it comes to trying to recover the data in the unfortunate instance of severe corruption.  As you will see later, though, the blob files are essentially variable length records so they will be harder to recover in the case of severe corruption.

There are several restrictions that are imposed on the data records in DBISAM.  These restrictions are very important and are as follows:

 	The fixed-length data records can contain up to 512 fields.

 	A field name may be mixed case but may not be longer than 30 characters and must begin with an alpha character (A-Z).  It may include spaces, but it's not recommended.

 	A field may be any of the following data types:

Data Type	Notes

String	Null-terminated up to a maximum length of 245 bytes

Integer	32-bit signed integer

Auto-Increment	32-bit signed integer starting with a seed value of 1 and a positive increment

SmallInt	16-bit signed integer

Word	16-bit unsigned integer

Boolean	Double-byte (word or integer size) boolean

Date	32-bit signed integer

Time	32-bit signed integer

Timestamp	64-bit double like TDateTime native data type in Delphi

Float	64-bit double (also includes Currency field type)

Currency	64-bit double

Blob	32-bit signed integer that contains a pointer to the beginning of the blob record in the blob file

Typed Binary	32-bit signed integer that contains a pointer to the beginning of the blob record in the blob file

Binary	32-bit signed integer that contains a pointer to the beginning of the blob record in the blob file

Formatted Memo	32-bit signed integer that contains a pointer to the beginning of the blob record in the blob file

Memo	32-bit signed integer that contains a pointer to the beginning of the blob record in the blob file

Graphic	32-bit signed integer that contains a pointer to the beginning of the blob record in the blob file

Bytes	Similar to String type but no null terminator, good for bit fields

BCD	64-bit signed integer with fixed decimal place, the number of decimal places cannot exceed 4

 	Fields can also contain definitions for min/max and required validity checks as long as these validity checks correctly match the data type for the field they are attached to.  The following is a list of constant values that can be used as default values and min/max checks and the corresponding data type(s) they are valid for.

Constant	Appropriate Data Types

True	Boolean

False	Boolean

Date (Current Date)	Date

TimeStamp

Time (Current Time)	Time

TimeStamp

Now (Current Date and Time)	TimeStamp

Special flags are stored in DBISAM records to track NULL values for fields.  String fields and BLOB fields are a special consideration when dealing with NULL values since, unlike numeric and date/time fields, strings and BLOBs are always considered NULL when they are empty.  Assigning an empty string to a string field or clearing the contents of a BLOB field will set the NULL flag to true for that field, whereas assigning a 0 to an integer field will not set the NULL flag to true.  Delphi provides a special method in the TField component called Clear that will set any field to NULL, regardless of type.

Locking in DBISAM is done similar to the method that is used for .DBF files in FoxPro, dBase, Clipper, etc.  Records are locked based upon a virtual offset byte past the end of file.  All records are locked by calling standard operating system API functions.  DBISAM locks the data file header when appending or deleting records so that record statistics can be properly updated in the data file header.

All data records in DBISAM are cached using a MRU, or most-recently-used, algorithm.  This optimizes disk access by allowing DBISAM to retrieve data records from it's in-memory cache instead of having to read them from disk.

All free space from deleted records is automatically re-used as necessary in DBISAM.  There is no need to run any utilities to reclaim deleted records or compact the data files.

The data files in DBISAM default to using an extension of .DAT, and this extension cannot be changed without making the file unusable to DBISAM.


Database System Overview Index Files
Overview of Database System

Index Files

The index files in DBISAM contain a fixed 1024-byte header which in itself contains up to 31 index headers and other index header information that pertains to the entire index file.  Following the index header are x number of index pages.  These index pages are structured in what is called a B-Tree, or in the particular case of DBISAM a "modified B-Tree" because of the nature of the index page links at the bottom of the tree.  There is one B-Tree per defined index (0 through a maximum of 33) stored in the index file.  A B-Tree is best pictured as an upside-down tree where the leaves are at the bottom and the trunk (or root as it's traditionally been called) is at the top.  B-Trees are the most commonly used index structure because of their fast access times.  Even with very large numbers of keys (hundreds of thousands) a B-Tree may only have to access 4 or so index pages to find any particular record.  In DBISAM, these access times get even better because the index pages are compressed to reduce their storage size on disk.  This technique results in fewer index pages needed to store the B-Tree on disk and improves the overall performance of DBISAM.  This compression is similar to that found in FoxPro. Also stored with each index key are key count statistics that allow DBISAM to quickly and easily determine how many records fall under a given portion of a B-Tree. This information provides the basis for logical sequence numbers and ranges with accurate record counts.  It also provides optimization information for filtering when DBISAM needs to determine how many index keys reside within a given range of values.

There are several restrictions that are imposed on the indexes in DBISAM.  These restrictions are very important and are as follows:

 	Each data file must have a primary index, there is no natural order in a DBISAM data file like there is in FoxPro or dBase, which both use the record number as the natural order.  In DBISAM the natural order is essentially the primary index.

A secondary index name may be mixed case but may not be longer than 30 characters and must begin with an alpha (A-Z) character.  It may include spaces, but it's not recommended.

The maximum key size for any index is 254 bytes and an index key can be comprised of up to 16 fields.  These fields can be any data type except for a blob field.

Indexes can also be marked as descending, instead of the default of ascending.  This is a permanent designation and requires a data file restructure to change, you cannot simply flip an index one way or the other during runtime operation.

Indexes can also be marked as case-insensitive, instead of the default of case-sensitive.  This is a permanent designation and requires a data file restructure to change.

Indexes can also be marked as unique, instead of the default of allowing duplicate keys. This is a permanent designation and requires a data file restructure to change. Please note that primary indexes are implicity always unique and never allow duplicate keys.

Locking in DBISAM is done similar to the method that is used for .CDX, .MDX. or .NTX files in FoxPro, dBase, Clipper, etc.  DBISAM locks the index file header when appending, updating, or deleting index keys so that key statistics can be properly updated in th index file header and to ensure that the current updates are completed for the entire B-Tree.  This is due to the fact that in some cases the entire B-Tree for an index could literally be reorganized to look nothing like it did before the update.

All index pages in DBISAM are cached using a MRU, or most-recently-used, algorithm.  This optimizes disk access by allowing DBISAM to retrieve index pages from it's in-memory cache instead of having to read them from disk.  The cache for the index pages is separate from the data records so that the data records do not unnecessarily get discarded or flushed to disk because of heavy index page activity such as the situation that exists when adding many keys for an individual data record to the index file.

DBISAM automatically re-uses all free space in index files. There is no need to run any utilities to reclaim deleted index pages or compact the index files.

The index files in DBISAM default to using an extension of .IDX, and this extension cannot be changed without making the file unusable to DBISAM.


Database System Overview Blob Files
Overview of Database System

Blob Files

The blob files in DBISAM contain a fixed 512-byte header containing information pertaining to the overall blob file followed by x number of variable-length blob blocks containing blob data. The size of the blob blocks are determined by the user and can be changed at any time The blob blocks are arranged in a linked-list structure for each blob record with the fixed-length record containing the pointer to the beginning blob block.  All blob blocks for the blob contain a reverse-pointer back to the data record in the data file to allow for easy repair in case the linked-list of blob blocks gets damaged due to corruption.  Without this reverse-pointer, repair would be impossible.

Blob files in DBISAM can contain virtually any type of variable-length data, from images to Delphi components to text files, and there is no logical restriction on the size of the any given blob record.  There are, however, physical hardware restrictions that come into play such as available memory because of the way DBISAM buffers entire blob records in memory to allow for proper interaction with the Delphi data access components.  Future improvements to DBISAM should alleviate this problem by writing blob records that are unusually large and are currently being buffered in memory to temporary storage on disk.  Please see the

topic Delphi 16-bit vs 32-bit for more information.

Locking in DBISAM is done similar to the method that is used for .FPT or .DBT files in FoxPro, dBase, Clipper, etc.  DBISAM locks the blob file header when appending, updating, or deleting blobs so that block statistics can be properly updated in the blob file header and to ensure that the current updates are completed for the entire blob.  This is due to the fact that in some cases the entire linked-list for a blob could literally be reorganized to look nothing like it did before the update.

All blob blocks in DBISAM are cached using a MRU, or most-recently-used, algorithm.  This optimizes disk access by allowing DBISAM to retrieve blob blocks from it's in-memory cache instead of having to read them from disk.  The cache for the blob blocks is separate from the data records so that the data records do not unnecessarily get discarded or flushed to disk because of heavy blob block activity such as the situation that exists when adding a large blob such as an image to the blob file.

DBISAM automatically re-uses all free space in blob files. There is no need to run any utilities to reclaim deleted blob blocks or compact the blob files.

The blob files in DBISAM default to using an extension of .BLB, and this extension cannot be changed without making the file unusable to DBISAM.


Database System Overview Low-Level Database Objects
Overview of Database System

Low-Level Database Objects

The basic database engine consists of a hierarchy of low-level objects for dealing with the data, index, and blob files.  Most of the code is straight Object Pascal with some BASM used in critical areas to boost performance.  The base object is the TFileHandler object.  This object deals with all of the basic file handling chores such as opening, closing, reading, writing, and locking.  The TFileHandler object is a direct descendant of TObject and is the ancestor of the TDataFile, TIndexFile, and TBlobFile objects that comprise the rest of the objects in DBISAM that deal with files.  The TDataFile object provides the only publicly visible interface for manipulating a data file via low-level method calls aside from using the Delphi data access components.  At this time this interface is not documented and it is not recommended that you call any low-level methods in the TDataFile object without first consulting with Elevate Software.


Database System Overview Data Access Components
Overview of Database System

Data Access Components

The data access components provide the widely accepted Delphi standard for accessing DBISAM data files.  In Delphi 1.02 and 2.01 the data access units, DB.DCU, DBTABLES.DCU, and DBGRIDS.DCU (Delphi 2.01 only) have been changed and re-compiled to hook directly into the DBISAM database engine and bypass the BDE altogether.  While this provides seamless integration for DBISAM, it does cause some confusion when dealing with things that are either not supported by DBISAM or are slightly different in their expected behavior.  These anomalies are documented in the following links:

 Overview of Delphi 1 Support

 Overview of Delphi 2 Support

Delphi 3 and 4 introduced the concept of the common TDataSet ancestor that allows for TDataSet descendants that implement data access for other database engines and formats outside of the BDE.  Because of this, the component names and some of the properties and methods that exist in the DBISAM TDataSet descendant, TDBISAMDataSet, have either been changed or removed altogether since they don't apply to DBISAM.  These differences are documented in the following links:

 Overview of Delphi 3 Support

 Overview of Delphi 4 Support


Before You Begin

There are some items to watch out for and keep in mind when using the DBISAM Database System.  These items can range from Delphi 16-bit vs 32-bit issues to restructuring issues and are categorized by topic below.

 Frequently Asked Questions

 Which Versions of Delphi are Supported

 Delphi 16-bit vs 32-bit

 DBISAM vs the BDE (Borland Database Engine)


Delphi 16-bit vs 32-bit

There are just a few differences between that should be considered when dealing with using DBISAM in both 16-bit and 32-bit applications that are accessing the same data.

Difference	Notes

BLOB Fields	In Delphi 1.02 (16-bit), there is a limit on how big a blob field's contents can be when using DBISAM.  That limit is directly tied to the segment size of 64k (65,536 bytes) and cannot be exceeded.  If you have applications that are written for Delphi 2.01, 3.0x, or 4.0x and Delphi 1.02 please be careful and plan ahead in determining how large your blob fields can or will get.  Under Delphi 2.01, 3.0x, or 4.0x (or any 32-bit version of Delphi going forward) the 64k limit does not exist and BLOBs can theoretically be as big as needed, but are essentially limited by available total memory available.  If using extremely large BLOBs in a 32-bit Delphi environment it also pays to plan ahead and make sure that your expectations are not exceeding an acceptable limit in total memory and demanding more memory than the typical machine will possess.

Regardless of environment, please keep in mind that DBISAM always buffers BLOBs in memory when records are being added or edited.  This is in contrast to the BDE, which will write overflow BLOB data to temp files on disk when they exceed an acceptable amount of memory consumption (acceptable is determined internally by the BDE).  For more information on the differences between DBISAM and the BDE see the topic DBISAM vs the BDE (Borland Database Engine).

BCD Fields	Only in Delphi 2.0 and higher did Borland introduce the Currency data type as a built-in scaled integer data type.  In the previous version of Delphi 1.02 Borland only included support for Floating point types that weren't very well suited to accurate rounding in financial applications.  Because of this limitation Delphi 1.02 converts all retrieved BCD field data to a floating-point data type (via the TBCDField .AsFloat property) for further manipulation in your application.  Under Delphi 2.0 and higher (DBISAM only supports Delphi 2.01, 3.0x, or 4.0x) Borland added the AsCurrency property so you can retrieve the BCD field data and maintain the proper rounding by using a Currency data type when you further manipulate the data. Please keep in mind when creating Delphi 1.02 and Delphi 2.0, 3.0x, or 4.0x applications that access the same data files: not only will your code be different but the results that get stored back to the data files in DBISAM could also be different due to the differences in rounding.

Auto-increment Fields	There is no auto-increment field type in Delphi 1.02 so keep this in mind when developing applications for both 16-bit and 32-bit platforms.  This is a limitation of Delphi 1.02, not DBISAM, therefore you can define auto-increment fields for any database but they will only show up as a TIntegerField in Delphi 1.02, whereas in Delphi 2.01 and 3 they will properly show up as a TAutoIncField.  Please note that this lack of support does not affect the functionality of an auto-increment field.  An auto-increment field will still increment properly for each record.

Filters	Filter support is not available when using the normal TTable component under Delphi 1.02.  You must use the TDBISAMTable component provided with DBISAM in order to take advantage of the filter support in DBISAM under Delphi 1.02.

In-Memory Tables	In Delphi 1.02 (16-bit), there is a limit on how big an in-memory table can be when using DBISAM.  That limit is directly tied to the segment size of 64k (65,536 bytes) and cannot be exceeded.  The size restriction of 64k is placed on each individual component of a data file.  What this means is that you may have a data file (.DAT) that's 32k in size, an index file (.IDX) that's 32k in size, and a blob file (.BLB) that's 32k in size and you will not be exceeding the maximum memory size of 64k.  However, if any one of these data file components grow beyond 64k you will receive an error under Delphi 1.02.  Under Delphi 2.01, 3.0x, or 4.0x (or any 32-bit version of Delphi going forward) the 64k limit does not exist and in-memory tables can theoretically be as big as needed, but are essentially limited by available total memory available.


DBISAM vs the BDE (Borland Database Engine)

There are several key differences between the BDE and the DBISAM that should be taken into account, especially when converting an existing application that uses the BDE over to the DBISAM Database System. Please note that all comparisons are done assuming usage of only the Paradox and dBase/FoxPro local database formats available in the BDE.  For numerous reasons Access is not included in this comparison. This list of items only includes differences, for a thorough review of the features in DBISAM please see the Overview of the Database System.

Difference	Notes

Queries (SQL and QBE)	DBISAM does not currently include support for querying, either by using SQL or QBE.  This is a feature that's being looked into for future versions and will be most likely last on the list of priorities.  In addition to SQL, DBISAM does not support stored procedures.

Batch Moves	DBISAM does not currently support batch moves or bulk inserts and updates.  This features is slated for Shipping Release 2 of DBISAM.

Filters	Both the BDE and DBISAM provide expression filters and a callback-based filter mechanism exposed as the OnFilterRecord event that allows you to filter on any type of arbitrary data.  The expression filters in both DBISAM and the BDE are optimized by the database engine.  What this means is that whenever an index (either primary or secondary) is available that satisifies a portion or all of the filter criteria, then that index is used to locate the appropriate records instead of scanning top to bottom through the actual data records.  Please remember that in both DBISAM and the BDE that the ixCaseInsensitive setting for the FilterOptions property affects which indexes are available (case-insensitive or not case-insensitive) for this optimization process, but only for string fields.  If you are setting a filter on a non-string field such as an Integer field the ixCaseSensitive setting has no bearing on the optimization process. If you need to find out whether a particular filter is optimizable just examine the FilterOptimizeLevel property of the TDBISAMTable component. DBISAM uses bitmaps and indexes to perform filter optimization in the same way that Rushmore and similar technologies are used with FoxPro and dBase. The record sequencing when filters are in effect is identical to that of the BDE as well as the record counts.  Also note that filter support is provided for Delphi 1.02 with DBISAM via the TDBISAMTable component, however Delphi 1.02 does not out of the box provide any filter support at all even though the 16-bit BDE supports it.

BLOBs	The BDE allows (in the Paradox data format) for the storage of a portion of the BLOB data for a given BLOB field to be stored in the actual data record in addition to storing the BLOB in a separate BLOB file.  DBISAM does not support this and more closely resembles the dBase data format where all of the BLOB data is stored in a separate BLOB file. Also, DBISAM always buffers BLOBs in memory when records are being added or edited.  This is in contrast to the BDE, which will write overflow BLOB data to temp files on disk when they exceed an acceptable amount of memory consumption (acceptable is determined internally by the BDE).

In-Memory Tables	The BDE alllows for the creation of in-memory tables that behave somewhat like a regular table, but are severly limited in several areas such as the ability to add and use indexes (both primary and secondary) and the ability to use BLOB fields.  Also, an in-memory table created through the BDE is automatically destroyed upon closing and cannot be shared by multiple TTable components in Delphi.  The low-level BDE calls to take advantage of in-memory tables are also quite confusing to most novice Delphi programmers.  DBISAM, on the other hand, overcomes all of these limitations and even allows in-memory tables to be shared by multiple TTable or TDBISAMTable components.  The only difference between a regular disk-based table and an in-memory table in DBISAM is that you cannot place locks on in-memory tables or records contained in them.  Also, to use in-memory tables in DBISAM is as simple as setting a Boolean property called InMemory for the desired TDBISAMTable component(s). Please keep in mind that, because in-memory tables in DBISAM act like regular disk-based data files, you must first create the table using CreateTable and delete the table DeleteTable to get rid of the table.  This means that you cannot open an in-memory table in design mode in the IDE.  DBISAM also allows you stream in-memory data files back and forth from any TStream-descendant using simple SaveToStream and LoadFromStream methods in the TDBISAMTable component.  This means that you can create embedded sub-tables that reside entirely inside of a BLOB field in one record.

Free Space Management	The BDE practices free space recycling in the Paradox format but not in the dBase or FoxPro formats.  In these formats free space is not recycled and after many inserts and deletes the data files tend to get bloated. This is primarily because with these formats the records are not physically deleted, only marked for deletion, and their corresponding index keys are kept in the index file.  DBISAM recycles all free space in data, index, and blob files transparently and without any user intervention required, and when a record is deleted, the space is marked as free and available for re-use immediately.

NULL Support	DBISAM includes complete NULL support that behaves identically to that of Paradox, although it is implemented in a safer and more thorough manner.  The rules for NULL support in DBISAM are as follows:

DBISAM NULL Rules

1	If a field has not been assigned a value it is NULL.

2	As soon as a field has been assigned a value it is not considered NULL anymore.  String fields and BLOB fields are an exception this rule.  When you assign a NULL value (empty string) to a String field the field will be set to NULL just as if you had called the Clear method of the TField.  When the contents of a BLOB field are empty, i.e. the length of the BLOB is 0, the field will be set to NULL just as if you had called the Clear method of the TField.

3	If the Clear method of a TField is called the field will be set to NULL.

4	NULL values are treated as separate, distinct values when used as an index key.  For example, let's say that you have a primary index comprised of one Integer field.  If you had a field value of 0 for this Integer field in one record and a NULL value for this Integer field in another record, DBISAM will not report a key violation error.  This is a very important point and should be considered when designing your data files.  As a general rule of thumb, you should always provide values for fields that are part of the primary index.

5	Auto-increment fields are never NULL.

Encryption and User Security	The BDE includes support for user security through encryption and passwords with the Paradox format.  DBISAM also supports encrypting a data file with a password, however it does not currently support a user-based security mechanism.  Whenever you attempt any operation on an encrypted data file in DBISAM you will be prompted for the password.  You should be extremely careful with this functionality since you will not be able to open an encrypted data file if you lose the password.

Indexes	The BDE supports several different indexing schemes for local databases through separate drivers.  DBISAM most closely resembles the Paradox data format in that it supports primary and secondary indexes, but it does offer some features that are found in the FoxPro .CDX and dBase .MDX formats also. There are some differences between the Paradox, dBase, and FoxPro indexes and the DBISAM indexes, however.

 Difference	Notes

Primary Indexes 	Paradox allows for data files with no primary index defined.  DBISAM must have a primary index defined for every data file.

Case-Insensitivity	Paradox supports case insensitive indexes for secondary indexes. DBISAM also support case-insensitive indexes, but for both primary and secondary indexes.

Secondary Indexes	Paradox stores secondary index definitions in separate files, one file for each separate index.  This is in addition to a separate file for the primary index.  DBISAM stores all primary and secondary indexes in one .IDX file, which cuts down on file handle usage and headaches associated with distribution.  This is similar to the .CDX and .MDX index formats.

Key Compression	Paradox and the dBase .MDX index formats do not include any type of index key compression at all, while the FoxPro .CDX format includes very good index key compression.  DBISAM splits the two, including duplicate byte compression but not trailing byte compression (the FoxPro .CDX format includes both).  The reason for this is that the speed of hard drives has gotten to the point that very thorough compression is more costly in terms of speed than actually just writing more data out to disk.

Descending Indexes	The Paradox format allows for descending secondary indexes in version 7.0 and above. DBISAM allows for descending indexes also, but for both primary and secondary indexes.

In addition to the index formats, the BDE supports several features for searching on indexes and setting ranges that are noteworthy.

Difference	Notes

Partial Field Search	The BDE will allow you to search on a partial field count of the entire active index.  For example, if you had a primary index on a Paradox data file that consisted of CustomerNum, OrderNum, and LineNum, the BDE would allow you to search on just CustomerNum to find the record you are looking for.  DBISAM also supports this feature in the exact same manner as the BDE.

Partial Field Range	The BDE also allows you to use this same principle when applying ranges to a data file, and again DBISAM fully supports this method of setting ranges.

Logical Sequence #'s	When using the Paradox data format with the BDE, you can retrieve a logical sequence number based upon the currently active index.  DBISAM supports this feature.

Exact Record Count	Paradox allows you to get an instantaneous and exact record count even when a range is currently set.  DBISAM also supports this feature.

International Support	DBISAM does not currently support alternate collation sequences and code pages for international support.  This feature is slated for Shipping Release 2.

Distribution	DBISAM can be compiled completely into your application and does not require any other DLLs or external components.  Runtime package support is also provided with the DBISAMDB.DPL package that is distributed with the Delphi 3 support and with the DBISAMDB.BPL package this is distributed with the Delphi 4 support.

Memory Usage	DBISAM does not pre-allocate memory for data, index, and blob buffers like the BDE does.  In contrast, DBISAM only allocates memory for caching on an as-needed basis and is restricted to the following limits:

Area of Usage	DBISAM Limits

Data Record Buffers	128k is the maximum amount of record buffer cache

Index Page Buffers	64k is the maximum amount of index page cache for each index defined.  For example, if you have 4 defined indexes (1 primary index and 3 secondary indexes) then the maximum amount of memory DBISAM will use is:

(64K * 4) = 256k

Blob Block Buffers	128k is the maximum amount of Blob block cache

 	Please remember that these figures are on a per data file basis and in shared mode (not opened exclusively) a data file will rarely ever come even close to hitting these maximum usage amounts.  For more information on index pages and other terms related to the database engine, please see Overview of the Database System.

Concurrency (Multi-User Usage)	The BDE in general, and the Paradox file format in particular, can be difficult to set up for proper multi-user use.  There is the .NET file, .LCK files, and the Local Share setting to deal with and improper settings can cause data refresh problems and in the worst case, data corruption.  DBISAM does not suffer from these same problems.  Automatic cache refresh mechanisms are built into the data format to ensure that DBISAM is always using the most recent data and all locking is done through the operating system.  There is absolutely nothing extra that you must do when writing an application for single-user or multi-user use.  All of the hard work is done for you, transparently, and the only task left up to you is copying the data files onto the network file server.

Transaction Support	Transaction support in the BDE for local databases is somewhat limited in the amount of records that can participate in a given transaction.  The highest limit currently imposed is 255 records and this depends upon whether you're using the dBase/Foxpro or Paradox database formats.  DBISAM does not impose any limits on transactions, you may have as many records participating in a transaction as disk space will allow.  DBISAM also allows you to set a Boolean TransactionsInMemory property for the TDBISAMTable component(s) that will use an in-memory transaction log file instead of a disk-based transaction log file.  Please keep in mind that neither the BDE or DBISAM offer fail-safe transactions, so do not rely on them to prevent data inconsistencies with complicated transactions that affect multiple files unless you can guarantee that the application will not get unexpectedly interrupted.

Performance	Shared use performance in the BDE on a network file server can vary from adequate to poor based upon your configuration.  Internal performance testing shows that, in shared use, DBISAM will outperform the BDE by a significant margin.  Please note, however, that the BDE is slightly faster than DBISAM when using data files that are opened exclusively.  This difference is largely related to the extra memory that the BDE allocates for buffering that DBISAM does not.  In other words, it is possible to make DBISAM as fast as the BDE with exclusive use simply by increasing the maximum amount of data that DBISAM can cache.


Which Versions of Delphi are Supported

DBISAM includes .DCU, design-time package, and run-time package (Delphi 3.0x .DPL and Delphi 4.0x .BPL) support for the following Delphi versions:

Delphi 1.02

Delphi 2.01

Delphi 3.0x (all versions of Delphi 3, including updates)

Delphi 4.0x (all versions of Delphi 4, including updates)


Overview of Delphi 2 Support

DBISAM includes replacement .DCUs for Delphi 2.01 only.  Delphi 2.01 can be ordered as an upgrade CD-ROM from Borland.  The three .DCUs replaced are:

 	DB.DCU  (the base TSession, TDatabase, TDataSet, TDBDataSet, and TField components)

DBTABLES.DCU  (the TTable, TBatchMove, TQuery, TStoredProc, and TField descendant components)

DBGRIDS.DCU (the TDBGrid component)

DBISAM also includes a .DCU for a TTable descendant called TDBISAMTable that provides additional properties, methods, and events to bring the Delphi 2.01 support for DBISAM closer to what is currently provided in Delphi 3.x and 4.x:

DBISAMTB.DCU  (the descendant TDBISAMTable component)

 Installation

 Differences Between Delphi/BDE and Delphi/DBISAM


Delphi 2 Installation

To install the replacement DCUs for DBISAM into the component library in Delphi 2.01, please perform the following steps in Delphi:

1	Select the Component option from the main menu

2	Select the Install option from the Component menu

3	At the BEGINNING of the Search Path edit control, type the following:

<Install Directory>\DELPHI2;

This will place the path where you installed the Delphi 2.01 components before the normal BDE-based Delphi data access components and will enable the DBISAM Database System for use under Delphi 2.01.  Be sure to include the semicolon between the newly inserted path and the existing library search path and be sure not to overwrite any of the existing library search path.

4	Select the OK button to proceed with rebuilding the component library using the DBISAM data access components

If you have any problems with this procedure please be sure to contact technical support for help.

To install the TDBISAMTable descendant component DCU for DBISAM into the component library in Delphi 2.01, please perform the following steps in Delphi:

1	Select the Component option from the main menu

2	Select the Install option from the Component menu

3	Select the Add button, which will bring forward the Add Module dialog

4	Select the Browse button on the Add Module dialog, and change directories to the Delphi2 subdirectory under the main directory where DBISAM was installed

5	Double-click on the DBISAMTB.DCU file

6	Select the OK button to proceed with rebuilding the component library with the newly added TDBISAMTable component


Delphi 2 Differences
Differences Between Delphi/BDE and Delphi/DBISAM in Delphi 2

There are several things that are different between the original Delphi .DCUs and the replacement .DCUs provided by DBISAM.  These differences are documented here by component:

 TSession Component

 TDatabase Component

 TQuery Component

 TStoredProc Component

 TBatchMove Component

 TTable Component

 TDBISAMTable Component


Delphi 2 TSession Component
Differences Between Delphi/BDE and Delphi/DBISAM in Delphi 2

TSession Component

The following is a listing of the properties and methods in the TSession component that have changed in behavior with DBISAM and the notes about the changes:

Property, Method, or Event	Notes

Locale Property	DBISAM does not currently provide for international support so the Locale property is ignored.

NetFileDir Property

PrivateDir Property	Both of these properties are ignored in the DBISAM TSession component.  The NetFileDir and PrivateDir properties are based on concepts specifically related to using Paradox data files and the BDE.

TraceFlags Property	The TraceFlags property is ignored in the DBISAM TSession component.

IsAlias Property

ConfigMode Property

AddAlias Method

AddStandardAlias Method

DeleteAlias Method

GetAliasNames Method

GetAliasDriverName Method

GetAliasParams Method

GetConfigParams Method

GetStoredProcNames Method

ModifyAlias Method

SaveConfigFile Method	These properties and methods are ignored in the DBISAM TSession component.  DBISAM does not support either alias names or stored procedures.  The ConfigMode property is essentially ignored in the DBISAM TSession component and will always return cmSession.

GetDriverNames Method

GetDriverParams Method

GetTableNames Method	These methods all still work as expected, the one difference being that the GetDriverNames method only returns one driver name - "DBISAM".


Delphi 2 TDatabase Component
Differences Between Delphi/BDE and Delphi/DBISAM in Delphi 2

TDatabase Component

The following is a listing of the properties and methods in the TDatabase component that have changed in behavior with DBISAM and the notes about the changes:

Property, Method, or Event	Notes

Locale Property	DBISAM does not currently provide for international support so the Locale property is ignored.

TransIsolation Property

StartTransaction Method

Commit Method

Rollback Method	DBISAM allows for transactions, and just like the BDE only one per database can be active at any given time.  When you start a transaction using the StartTransaction method of the TDatabase component, any TTable components that are connected to this TDatabase component are now involved in the current transaction.  Any changes made to these TTable components will be logged in the appropriate transaction log and will be committed or rolled back as a group under the current transaction. You must be very careful when using multiple TDatabase components with active transactions on the same TTable components, since either rolling back any changes or committing any changes could cause great confusion as to how the data files actually got into their current state.  It is normally only a good idea to have one active transaction on any given TTable component and to make sure that your TTable components are not accidentally attached to different databases.  Also, if you do not explicitly use a TDatabase component and instead rely on the temporary TDatabase component ( this TDatabase component is created for TTable components that use a path name for the DatabaseName property), be sure to remember that all TTable components in the current application will be attached to the same temporary database.

The transaction isolation level property of the TDatabase component doesn't need to be set to anything in particular to allow for proper usage of the transactions in DBISAM since this property is ignored.

Finally, the default Delphi TDatabase component does not ensure that the TTable components involved in the current transaction are all in the dsBrowse state, or, in other words, not editing, adding, filtering, or searching, when it commits or rolls back an existing transaction.  In the DBISAM replacement TDatabase component all TTable components are forced into browse mode before any transaction is rolled back or committed.  This means that any records being edited, added, or searched on will be posted using the standard Post method of TTable component if the transaction is being committed and cancelled if the transaction is being rolled back.

Params Property	The only parameters necessary in the Params property for the DBISAM TDatabase component is the PATH parameter.  It still requires the same syntax as the default Delphi TDatabase component:

PATH=X:\MYDIR

AliasName Property	The AliasName property will always be blank since DBISAM does not support alias names.  You must always provide a DatabaseName and specify the DriverName (see next issue).

DriverName Property	The only driver name available under the DriverName property for the DBISAM TDatabase component is the "DBISAM" driver.  You still need to select the driver name, it will not be selected automatically.

SssionAlias Property	The SessionAlias property is essentially ignored by the DBISAM TDatabase component and will always return False.

TraceFlags Property	The TraceFlags property is ignored in the DBISAM TDatabase component.

ApplyUpdates Method	DBISAM does not support Cached Updates so the ApplyUpdates method is ignored in the DBISAM TDatabase component.

FlushSchemaCache Method	DBISAM does not cache any schema information for data files, so the FlushSchemaCache method is ignored.

OnLogin Event	User names and logging in are not necessary when using DBISAM, and so this functionality has been disabled.  The OnLogin event will never be called and any USER NAME parameter in the Params property of the TDatabase component will be ignored.


Delphi 2 TQuery Component
Differences Between Delphi/BDE and Delphi/DBISAM in Delphi 2

TQuery Component

DBISAM does not support SQL queries so all functionality related to the TQuery component has been disabled.  DO NOT USE THIS COMPONENT WITH DBISAM.


Delphi 2 TStoredProc Component
Differences Between Delphi/BDE and Delphi/DBISAM in Delphi 2

TStoredProc Component

DBISAM does not support stored procedures so all functionality related to the TStoredProc component has been disabled.  DO NOT USE THIS COMPONENT WITH DBISAM.


Delphi 2 TBatchMove Component
Differences Between Delphi/BDE and Delphi/DBISAM in Delphi 2

TBatchMove Component

DBISAM does not currently support batch moves so all functionality related to the TBatchMove component has been disabled.  DO NOT USE THIS COMPONENT WITH DBISAM.


Delphi 2 TTable Component
Differences Between Delphi/BDE and Delphi/DBISAM in Delphi 2

TTable Component

The following is a listing of the properties and methods in the TTable component that have changed in behavior with DBISAM and the notes about the changes:

Property, Method, or Event	Notes

Locale Property

DBLocale Property	DBISAM does not currently provide for international support so the Locale and DBLocale properties are ignored.

KeyExclusive Property	DBISAM does not support exclusive keys in ranges and searches so the KeyExclusive property is ignored.

TableType Property	The TableType property is set to ttDefault by default and cannot be changed since the default table type for DBISAM is DBISAM tables.  Paradox and dBase access via the BDE concurrently with DBISAM is not supported.

LockTable Method

UnlockTable Method	DBISAM only supports locking an entire to prevent other users from writing to the table, not reading the table, so the LockTable and UnlockTable methods ignore the parameter indicating the type of lock (ltRead or ltWrite).

BatchMove Method	Batch moves (and the TBatchMove component) are not currently supported in DBISAM so the BatchMove method is ignored.

CreateTable Method

AddIndex Method	There are several differences between how creating tables using the CreateTable method is handled in the default Delphi TTable component and the BDE versus how it is handled in the DBISAM TTable component.

When adding field definitions for blob fields such as memos or graphics, Paradox and the BDE allow you to specify a field size that indicates how much of the current blob field contents should be stored directly in the data record.  DBISAM does not support this feature, so the field size for blob fields should always be set to 0 as indicated in the following example:

 with Table1 do

  begin

  Active := False;

  DatabaseName := 'Delphi_Demos';

  TableName := 'CustInfo';

  TableType := ttDefault;

  with FieldDefs do

    begin

    Clear;

    Add('Field1', ftInteger, 0, True);

    Add('Field2', ftMemo, 0, False); { <--- With DBISAM tables the field size must be 0 for blob fields }

    end;

  with IndexDefs do

    begin

    Clear;

    Add('', 'Field1', [ixPrimary]);

    end;

  CreateTable;

  end;

The following TField components are considered blob fields:

 	TMemoField

TGraphicField

TBlobField

There are some options used when adding index definitions used in the CreateTable method, and also when using the AddIndex method, that are handled differently than the default Delphi TTable component.

Option	Notes

ixUnique 	This option is used with the BDE and Paradox and dBase tables to specify a unique index. In DBISAM the unique option behaves in the same manner as Paradox.  The unique option enforces that duplicate index keys for the specified index will not be allowed in the data file.  The uniqueness of index keys are enforced automatically for primary indexes (defined using the ixPrimary option alone).

ixCaseInsensitive	DBISAM does support case-insensitive indexes and the ixCaseInsensitive option for both primary and secondary indexes.

ixNonMaintained	This option is used with the BDE and Paradox tables to specify indexes that are not maintained automatically by the BDE when updating the table.  DBISAM does not support this feature so this option is ignored.

ixDescending	DBISAM does support descending indexes and the ixDescending option for both primary and secondary indexes.  An example of using the CreateTable to create a table using both primary and secondary indexes, ascending and descending is as follows:

with Table1 do

  begin

  Active := False;

  DatabaseName := 'Delphi_Demos';

  TableName := 'CustInfo';

  TableType := ttDefault;

  with FieldDefs do

    begin

    Clear;

    Add('Field1', ftInteger, 0, True);

    Add('Field2', ftString, 20, False);

    Add('Field3', ftDate, 0, False);

    end;

  with IndexDefs do

    begin

    Clear;

    Add('', 'Field1', [ixPrimary]); {<-- This is an ascending primary index, you could add the ixDescending option if you wanted to make this primary index descending }

    Add('Field2Index', 'Field2', []);  {<-- This index definition is an ascending secondary index }

    Add('Field3Index', 'Field3', [ixDescending]);  {<-- This index definition is a descending secondary index }

    end;

  CreateTable;

  end;

CachedUpdates Property

UpdateObject Property

UpdateRecordTypes Property

UpdatesPending Property

ApplyUpdates Method

CancelUpdates Method

CommitUpdates Method

RevertRecord Method

OnUpdateError Event

OnUpdateRecord Event	DBISAM does not support cached updates, so the properties, methods, and events listed are ignored.

ExpIndex Property	DBISAM does not support expressions in indexes so the ExpIndex property will always be False.

IndexFiles Property

OpenIndexFile Method

CloseIndexFile Method	DBISAM does not support specifying an external index file for use with a TTable so the properties and methods listed are ignored.

OnServerYield Event	DBISAM is not a client-server database system so the OnServerYield event will never be triggered.


Frequently Asked Questions

The following is a list of frequently asked questions and their answers.  Hopefully this will help you better understand how DBISAM works and integrates into Delphi.

 Do I have to pack or reorganize DBISAM data files like in dBase or FoxPro to regain deleted records in the data files ?

No, DBISAM automatically re-uses all free space in data, index, and blob files.

 Are there any special considerations when moving a single-user application using DBISAM to multi-user on a network ?

No, DBISAM automatically manages all cache refresh and multi-user locking issues transparently.

 I need to put some data files on a CD-ROM that will then only be accessible as Read-Only from my application, do I have to do anything special to do this and can DBISAM handle this ?

Yes, DBISAM can handle this situation.  All you have to do is make sure that all of the data files being accessed in your application are opened Read-Only.  The following is an example of opening up a TTable component in ReadOnly mode:

MyTable:=TTable.Create(Application);

MyTable.DatabaseName:='c:\testdb';

MyTable.TableName:='customers.dat'

MyTable.ReadOnly:=True;

MyTable.Active:=True { or MyTable.Open }

 	Please note that DBISAM will automatically open the data file as Read-Only if it encounters that the data file is flagged as Read-Only at the operating system level.  This is the case with CD-ROMs and so you don't need to explicitly open the data file as ReadOnly, however it's good practice to do so.

Also, please note that DBISAM will optimize all data accesses when a data file is marked as Read-Only.  Since no writes to the data file can occur, DBISAM essentially treats the data file as if it were opened exclusively, increasing performance by a large degree.

 I've got my data in another format besides Paradox or dBase and I want to convert it into DBISAM format.  How do I do this ?

When using the Delphi 1.02 or 2.01 interface support for DBISAM this is impossible because DBISAM does not support using the BDE and DBISAM at the same time in these environments.  The only option in this case is to use the BDE and/or ODBC to convert the data into Paradox or dBase format and then use the BDE Database Transfer Utility to move the data from Paradox or dBase format into DBISAM format.  When using the Delphi 3.0x and above interface support for DBISAM you can have multiple TDataSet descendant components accessing different data formats at the same time.  A data conversion can be accomplished by simply copying records from one TDataSet descendant component to the other by looping through the TFields and using the Assign method to assign the contents of a TField in one TDataset descendant component to the other.  Please note, do not attempt to copy entire records at a time as a method of transferring data from one format to another.  DBISAM may use an entirely different record layout than the one being used as the source of the data.  Corruption and a general failure to work correctly may result.

The following is an example of looping through the TFields and copying data from one TDataset descendant to another (Delphi 3.0x and above only):

SourceDataSet:=TMyExistingDataSet.Create(Application);

SourceDataSet.DatabaseName:='MainServer';

SourceDataSet.TableName:='CUSTOMER';

SourceDataSet.Active:=True;

DestDataSet:=TDBISAMTable.Create(Application);

DestDataSet.DatabaseName:='c:\testdb';

DestDataSet.TableName:='customer.dat';

DestDataSet.Active:=True;

SourceDataSet.First;

while not SourceDataSet.EOF do

  begin

  DestDataSet.Insert;

  for I:=0 to SourceDataSet.FieldCount-1 do

  DestDataSet.FieldByName(SourceDataSet.Fields[I].FieldName). { continued }

Assign(SourceDataSet.Fields[I]);

  DestDataSet.Post;

  SourceDataSet.Next;

  end;

SourceDataSet.Close;

DestDataSet.Close;

Please note that this example assumes that the source and destination dataset field names will be the same and it does not deal with copying the structure or indexes, it simply copies the data.

 How do I get DBISAM to work with Infopower and other 3rd party data-aware components ?

It depends upon two things:

1	What version of Infopower you are using (if using Infopower)

If you are using Delphi 1.02 and 2.01 the Infopower support is restricted to making direct BDE calls internally and so will not work properly with DBISAM without modifications to the source code.  If you own the source code to Infopower and would like information on how to modify the code to replace the direct BDE calls with calls to the DBISAM engine, please let us know and we'll be more than happy to help out.  If you're using the latest 3.01 version of Infopower you can use any 3rd party TDataset descendant such as DBISAM without having to worry about direct BDE calls.  You can find an Delphi 3 Infopower-compatible TDataset descendant (with source) in the <INSTALLDIR>\INFOPOWR directory after installing DBISAM.

2	Whether the 3rd party data-aware control makes direct BDE calls or not (if not using Infopower)

For other 3rd party data-aware components the source code is also necessary if the component makes direct BDE calls.  This can also be changed to support DBISAM and we'll be happy to help out here also.  If you're a 3rd party data-aware component vendor and would like to distribute DBISAM-compatible versions of your product for Delphi 1.02 and 2.01 please contact us.  We would be more than happy to help get your product quickly and easily integrated with DBISAM.  If you're producing a Delphi 3.0x or 4.0x data-aware component and stick to using just the standard TDataSet methods, you're all set and everything should be 100% compatible with DBISAM.  Just to be sure, though, please review the differences between the BDE and DBISAM here to make sure that you're not counting on a feature that's not supported in DBISAM.

 Do I have to worry about corruption ?

Just like any other local database format, DBISAM is susceptible to corruption caused by someone physically turning off the machine or general loss of power.  The circumstances in which this type of failure occurs and the open mode of the data file(s) (exclusive or shared) will determine what type of corruption you will encounter, if any.  For example, if DBISAM is in the middle of adding a record to a shared data file when the power goes out, the record being added will definitely be lost in the bit bucket.  However, due to the caching involved and the fact that the buffers don't actually get flushed to disk until after the append operation there's a large chance that there also won't be any corruption.  Corruption will definitely occur if the failure occurs while the buffers are getting flushed to disk.  Keep in mind that the when a data file is opened in exclusive mode cached data will get flushed to disk in a seemingly random manner so severe corruption is much more likely after a failure in such a situation.  If you think you have corruption in your data file(s), you should immediately run the Repair option in the Database System Utility (DBSYS.EXE) on the data file(s) in question.

 Does DBISAM support ranges and filters ?

DBISAM fully supports ranges, including partial field ranges (when the range set does not include all of the fields in the active index), logical sequence numbers in a range (1..records in the range), and accurate record counts with ranges set.  DBISAM also fully supports optimized expression filters and callback filtering via the OnFilterRecord event. You can find out if a filter is optimizable through the FilterOptimizeLevel property of the TDBISAMTable component.  You may combine ranges, expresssion filters, and callback filters in any manner you wish.

 Does DBISAM support NULL values in fields ?

DBISAM fully supports NULL values for all field types.

 Does DBISAM support auto-increment fields ?

DBISAM supports defining 1 field as an auto-increment field in a data file.  The incrementing logic is multi-user safe and the an auto-increment field can be used without problems as a primary index.

 Can I restructure data files in code ?

Yes, DBISAM provides a TTable descendant called TDBISAMTable for use with Delphi 1.02 and 2.01 that provides restructure facilities in a method called RestructureTable that is similar to the CreateTable method, and the TDBISAMTable component for use with Delphi 3.0x and Delphi 4.0x also provides the RestructureTable method.

 How do I report progress back to the user for indexing and other bulk operations ?

DBISAM provides a TTable descendant called TDBISAMTable for use with Delphi 1.02 and 2.01 that provides progress events for indexing (OnIndexProgress), repairing data files (OnRepairProgress), and restructuring data files (OnRestructureProgress), and the TDBISAMTable component for use with Delphi 3.0x and 4.0x also provides these same events.

 Do I have to do anything special to install DBISAM at a customer's site ?

No, your application will only need to either create the data files it needs from scratch or ship them with the application.  DBISAM provides the ability to reverse-engineer data files using the Database System Utility so that in a couple of mouse clicks you can have a complete Delphi unit for creating your data files in code.

 I'm trying to set a range on a string field and no records are showing up, is this a bug ?

No, the Data Access components in Delphi do not allow setting ranges on partial fields.  The comparisons for setting the range are done on the entire field for the beginning and ending values of the range.  You need to make sure that the ending values of the range encompass the maximum value you would like to see included in the range.

For example, let's say that you have a secondary index called LastName that consists of the fields LastName (20 characters long) and FirstName (15 characters long), in that order.  You have set the active index for the table component to this index and would like to set a range on all records that begin with the letter 'L'.  At first glance it would seem that the following code would do what you want:

MyTable.SetRange(['L'],['L']);

But unfortunately this will only return records that contain the letter 'L'.   To make sure that the range includes all LastName values that begin with the letter 'L' you must use the following code:

MyTable.SetRange(['L'],['Lzzzzzzzzzzzzzzzzzzz']);

You could also use chr(255) instead of the lowercase 'z' to achieve the same results, although it might be a little more difficult.  Please keep in mind also that all range settings are currently case-sensitive.

You could set the range a little differently using the KeyExclusive property, but unfortunately DBISAM does not currently support the KeyExclusive property when setting ranges or searching for values.  This feature is slated for Shipping Release 2 of DBISAM.

 I accidentally deleted a field while restructuring a data file, and I need to get the data back.  How do I do that ?

 	DBISAM makes backup copies of all data files during a restructure whenever a field is changed, added, or deleted.  The backup files have the same root file name but with different extensions for the data (.DBK), index (.IBK), and blob (.BBK) files. Just copy these files to their respective data (.DAT), index (.IDX), and blob (.BLB) file names and they're ready to be used as the regular data files.

 I've got an application containing one datamodule with a TDatabase component and several TDBISAMTable components.  In this same application there are several forms with private TDBISAMTable components that point to the TDatabase component in the datamodule.  Every time I open up my project for this application I get an 'DBISAM Error #11010  Invalid path or filename for <.DAT file name> for each private TDBISAMTable on these forms.  What is causing this error ?

This is a problem caused by two important things:

1) You don't have your datamodule open in design mode when Delphi attempts to open up these forms

2) The private TDBISAMTable components on the forms are set to Active so that Delphi will attempt to open them

The cause of this problem is that, in design mode, Delphi cannot find any TDatabase components that are not open, in this case the datamodule is not open at the time that the forms containing the private TDBISAMTable components are opened.  What happens is that, because the TDatabase component is not available (and it contains the path where the tables are located), Delphi tries to open up the TDBISAMTable components using no path at all, or in the current directory.

The solution to the problem is to either not set your TDBISAMTable's Active property to True in design mode, or make sure that the datamodule or form containing the TDatabase component is always opened first in your project.

 I tried to use the DBISAM Database System Utility to open up some C-ISAM data files and it failed to open them.  Is DBISAM format-compatible with C-ISAM files or will it be in the future ?

No, the only thing DBISAM shares with C-ISAM (Informix) data files is the name and there is no intention of making DBISAM format-compatible with C-ISAM data files in the future.

 What is the difference between the free trial version of DBISAM and the regular version of DBISAM that one purchases ?

The only difference is the trial version contains a nag dialog that appears once during the initialization of DBISAM.

 What options are availale if my client insists on having source code for DBISAM ?

 	Elevate Software will provide interface code (the DB.PAS, DBTABLES.PAS, DBGRIDS.PAS, and DBISAMTB.PAS units) to those that request it.  We are unable to provide source code to the database engine itself (DBISAM.PAS, DBINDX.PAS, DBBLOB.PAS, or DBBASE.PAS).

  With SQL you can create another table and back up your data files.  How do I do this in DBISAM ?

DBISAM provides a TTable descendant called TDBISAMTable for use with Delphi 1.02 and 2.01 that provides copying facilities in a method called CopyTable that is similar to the RenameTable and DeleteTable methods, and the TDBISAMTable component for use with Delphi 3.0x and 4.0x also provides the CopyTable method.

 Is it possible to convert MS Access tables to DBISAM and back ?

Elevate Software has not tested transferring Access tables using the BDE Database Transfer Utility and cannot guarantee that such a transfer will work.  We will let everyone know if and when we provide such facilities.

 Is DBISAM thread-safe ?  I've used TDBISAMSession with a thread and it seems to be OK.

Elevate Software has not tested DBISAM within threads and therefore cannot ensure that using DBISAM in such a manner will work.  We will let everyone know when we've tested DBISAM and threads completely and can guarantee that it will work.

 In multi-user mode does DBISAM employee page-locking or record locking ?

DBISAM uses record-level locking only.

 Are DBISAM records fixed-length or variable-length ?  Would a string field of 50 bytes always use 50 bytes of storage even if the data only required ten bytes ?

DBISAM data records are fixed-length records so yes a string field of 50 bytes would always consume 50 bytes of storage.

 What is the granularity of the BLOB fields ? Do they always consume some multiple of a minimum block size, or are they truly variable in length ?

The BLOB files in DBISAM are based upon a default block size of 512 bytes. However, this block size may be changed when creating a new data file and at any time by simply restructuring the data file.  The valid block sizes are 64 bytes to 64k bytes.  Because the block sizes are fixed it's very well possible to have slack space in the blocks.  For example, a memo field that contains 400 bytes will consume 512 bytes on disk if the block size were left at the default of 512 bytes.  The ideal blob block size that minimizes the amount of slack space is essentially an average of the sizes of all of the blob fields for the data file.

 Does DBISAM support C++Builder ?  If not, is support for C++Builder planned for a future release ?

DBISAM currently does not support C++Builder. However, we do plan to offer C++Builder support in the near future as soon as the Delphi release of DBISAM is shipping.

 Does Elevate Software offer discounts to educational institutions and/or students ?

Yes, there is a 10% discount off of the normal price of DBISAM for educational and governmental institutions as well as for full-time students at an educational institution. There is no special verification needed, just the name of the institituion is all that is required.


Overview of Delphi 3 Support

DBISAM includes a TDataset descendant component for Delphi 3.  The following is the list of files that make up the Delphi 3 support:

 	DBISAMDB.DPL  (The design-time and run-time package for DBISAM, includes the TDBISAMSession, TDBISAMDatabase, TDBISAMDataset (non-visible component), and TDBISAMTable components)

 	DBISAMTB.DCU  (The compiled unit that contains all of the components in the package)

 	DBISAMRG.DCU (The compiled registration unit for all of the components in the package and their associates property editors)

 	DBISAMMS.DCU (The compiled unit for the master-detail property editor)

 	DBISAMCN.DCU (The compiled unit for all of the constants referenced in the DBISAM interface units)

 Installation

 Differences Between Delphi/BDE and Delphi/DBISAM


Delphi 3 Installation

To install the design-time package (DBISAMDB.DPL) for DBISAM into the component library in Delphi 3 and above, please perform the following steps in Delphi:

1	Select the Component option from the main menu

2	Select the Install Packages option from the Component menu

3	Select the Add button from the Install Packages dialog.  This will bring forward an open file dialog.  In this dialog type in the following name:

<Install Directory>\DELPHI3\DBISAMDB.DPL

Selecting the OK button will then install the design-time package for DBISAM into the Delphi environment.  The DBISAM components will show up on the Data Access tab of the component palette.

Before you can compile any projects using DBISAM you must make sure that the global search path in Delphi 3 includes the path where the DBISAMDB.DPL file is located.

To complete the installation by adding the location of the DBISAM.DPL design-time package to the library search path please perform the following steps in Delphi:

1	Select the Tools option from the main menu

2	Select the Environment Options option from the Tools menu

3	Select the Library Path edit control and move the cursor to the end of the field and type in:

;<Install Directory>\DELPHI3

Please be sure to include the semicolon before the DBISAM path in order to separate it from the rest of the existing library search path.

If you have any problems with this procedure please be sure to contact technical support for help.


Delphi 3 Differences
Differences Between Delphi/BDE and Delphi/DBISAM in Delphi 3

There are several things that are different between the original Delphi TSession, TDatabase, and TTable components and the replacement components TDBISAMSession, TDBISAMDatabase, and TDBISAMTable provided by DBISAM.  The TQuery, TStoredProc, and TBatchMove components have been removed in the DBISAM support for Delphi 3, there are no equivalent components available in DBISAM.  Please also note that in order to use BLOB streams in DBISAM you must use the provided TDBISAMBlobStream object (located in the DBISAMTB.DCU unit) instead of the TBlobStream object used with the BDE. The two are identical in function and only differ only in name.  The differences between the new TDBISAMxxxxxx components and the original BDE components is documented here by component:

 TDBISAMSession Component

 TDBISAMDatabase Component

 TDBISAMTable Component


Delphi 3 TDBISAMSession Component
Differences Between Delphi/BDE and Delphi/DBISAM in Delphi 3

TDBISAMSession Component

The following is a listing of the properties and methods in the TDBISAMSession component that have changed in behavior with DBISAM and the notes about the changes:

Property, Method, or Event	Notes

Locale Property	DBISAM does not currently provide for international support so the Locale property has been removed

NetFileDir Property

PrivateDir Property	Both of these properties are removed in the TDBISAMSession component.  The NetFileDir and PrivateDir properties are based on concepts specifically related to using Paradox data files and the BDE.

TraceFlags Property	The TraceFlags property is removed in the TDBISAMSession component.

SQLHourGlass Property	The SQLHourGlass property is removed in the TDBISAMSession component.

IsAlias Property

ConfigMode Property

AddAlias Method

AddDriver Method

AddStandardAlias Method

DeleteAlias Method

DeleteDriver Method

GetAliasDriverName Method

GetAliasNames Method

GetAliasParams Method

GetConfigParams Method

GetDriverNames Method

GetDriverParams Method

GetStoredProcNames Method

ModifyAlias Method

ModfifyDriver Method

SaveConfigFile Method	These properties and methods have been removed in the TDBISAMSession component.  DBISAM does not support either alias names or stored procedures and only deals with one driver which is the DBISAM database system itself.


Delphi 3 TDBISAMDatabase Component
Differences Between Delphi/BDE and Delphi/DBISAM in Delphi 3

TDBISAMDatabase Component

The following is a listing of the properties and methods in the TDBISAMDatabase component that have changed in behavior with DBISAM and the notes about the changes:

Property, Method, or Event	Notes

Locale Property	DBISAM does not currently provide for international support so the Locale property has been removed.

TransIsolation Property

StartTransaction Method

Commit Method

Rollback Method	DBISAM allows for transactions, and just like the BDE only one per database can be active at any given time.  When you start a transaction using the StartTransaction method of the TDBISAMDatabase component, any TDBISAMTable components that are connected to this TDBISAMDatabase component are now involved in the current transaction.  Any changes made to these TDBISAMTable components will be logged in the appropriate transaction log and will be committed or rolled back as a group under the current transaction. You must be very careful when using multiple TDBISAMDatabase components with active transactions on the same TDBISAMTable components, since either rolling back any changes or committing any changes could cause great confusion as to how the data files actually got into their current state.  It is normally only a good idea to have one active transaction on any given TDBISAMTable component and to make sure that your TDBISAMTable components are not accidentally attached to different databases.  Also, if you do not explicitly use a TDBISAMDatabase component and instead rely on the temporary TDBISAMDatabase component ( this TDBISAMDatabase component is created for TDBISAMTable components that use a path name for the DatabaseName property), be sure to remember that all TDBISAMTable components in the current application will be attached to the same temporary database.

DBISAM only supports "dirty read" transactions so the TransIsolation property of the TDBISAMDatabase has been removed.

Finally, the default Delphi TDatabase component does not ensure that the TTable components involved in the current transaction are all in the dsBrowse state, or, in other words, not editing, adding, filtering, or searching, when it commits or rolls back an existing transaction.  In the DBISAM replacement TDatabase component all TTable components are forced into browse mode before any transaction is rolled back or committed.  This means that any records being edited, added, or searched on will be posted using the standard Post method of TTable component if the transaction is being committed and cancelled if the transaction is being rolled back.

Params Property

Directory Property	The Params property has been removed and it's functionality for specifying the path for a TDBISAMDatabase component has been replaced with the Directory property.  This property specifies which directory the database will use for opening up data files for use as TDBISAMTable components.

AliasName Property	DBISAM does not support aliases so the AliasName property has been removed.

DriverName Property	DBISAM only supports one driver, the DBISAM Database System, so this property has been removed.

LoginPrompt Property

OnLogin Event	User names and logging in are not necessary when using DBISAM so the LoginPrompt property and the OnLogin event have been removed.

SessionAlias Property	DBISAM does not support aliases so the SessionAlias property has been removed.

TraceFlags Property	The TraceFlags property has been removed.

ApplyUpdates Method	DBISAM does not support Cached Updates so the ApplyUpdates method has been removed.

FlushSchemaCache Method	DBISAM does not cache any schema information for data files, so the FlushSchemaCache method has been removed.


Delphi 3 TDBISAMTable Component
Differences Between Delphi/BDE and Delphi/DBISAM in Delphi 3

TDBISAMTable Component

The following is a listing of the properties and methods in the TDBISAMTable component that have changed in behavior with DBISAM and the notes about the changes:

Property, Method, or Event	Notes

Locale Property

DBLocale Property	DBISAM does not currently provide for international support so the Locale and DBLocale properties have been removed.

KeyExclusive Property	DBISAM does not support exclusive keys in ranges and searches so the KeyExclusive property has been removed.

TableLevel Property	DBISAM does not support different table levels, or versions, currently so the TableLevel property has been removed.

TableType Property	There is only one table type for DBISAM so this property has been removed.

LockTable Method

UnlockTable Method	DBISAM only supports locking an entire to prevent other users from writing to the table, not reading the table, so the LockTable and UnlockTable methods do not accept a parameter indicating the type of lock (ltRead or ltWrite) like the default Delphi TTable component does.

BatchMove Method	Batch moves (and the TBatchMove component) are not currently supported in DBISAM so the BatchMove method has been removed.

CreateTable Method

AddIndex Method	There are several differences between how creating tables using the CreateTable method is handled in the default Delphi TTable component and the BDE versus how it is handled in the TDBISAMTable component.

When adding field definitions for blob fields such as memos or graphics, Paradox and the BDE allow you to specify a field size that indicates how much of the current blob field contents should be stored directly in the data record.  DBISAM does not support this feature, so the field size for blob fields should always be set to 0 as indicated in the following example:

with DBISAMTable1 do

  begin

  Active := False;

  DatabaseName := 'Delphi_Demos';

  TableName := 'CustInfo';

  with FieldDefs do

    begin

    Clear;

    Add('Field1', ftInteger, 0, True);

    Add('Field2', ftMemo, 0, False);  { <--- With DBISAM tables the field size must be 0 for blob fields }

    end;

  with IndexDefs do

    begin

    Clear;

    Add('', 'Field1', [ixPrimary]);

    end;

  CreateTable;

  end;

The following TField components are considered blob fields:

 	TMemoField

TGraphicField

TBlobField

There are some options used when adding index definitions used in the CreateTable method, and also when using the AddIndex method, that are handled differently than the default Delphi TTable component.

Option	Notes

ixUnique 	This option is used with the BDE and Paradox and dBase tables to specify a unique index. In DBISAM the unique option behaves in the same manner as Paradox.  The unique option enforces that duplicate index keys for the specified index will not be allowed in the data file.  The uniqueness of index keys are enforced automatically for primary indexes (defined using the ixPrimary option alone).

ixCaseInsensitive	DBISAM does support case-insensitive indexes and the ixCaseInsensitive option for both primary and secondary indexes.

ixNonMaintained	This option is used with the BDE and Paradox tables to specify indexes that are not maintained automatically by the BDE when updating the table.  DBISAM does not support this feature so this option is ignored.

ixDescending	DBISAM does support descending indexes and the ixDescending option for both primary and secondary indexes.  An example of using the CreateTable to create a table using both primary and secondary indexes, ascending and descending is as follows:

with DBISAMTable1 do

  begin

  Active := False;

  DatabaseName := 'Delphi_Demos';

  TableName := 'CustInfo';

  with FieldDefs do

    begin

    Clear;

    Add('Field1', ftInteger, 0, True);

    Add('Field2', ftString, 20, False);

    Add('Field3', ftDate, 0, False);

    end;

  with IndexDefs do

    begin

    Clear;

    Add('', 'Field1', [ixPrimary]); {<-- This is an ascending primary index, you could add the ixDescending option if you wanted to make this primary index descending }

    Add('Field2Index', 'Field2', []);  {<-- This index definition is an ascending secondary index }

    Add('Field3Index', 'Field3', [ixDescending]);  {<-- This index definition is a descending secondary index }

    end;

  CreateTable;

  end;

CachedUpdates Property

UpdateObject Property

UpdateStatus Property

UpdateRecordTypes Property

UpdatesPending Property

ApplyUpdates Method

CancelUpdates Method

CommitUpdates Method

RevertRecord Method

OnUpdateError Event

OnUpdateRecord Event	DBISAM does not support cached updates, so the properties, methods, and events listed have been removed.

ExpIndex Property	DBISAM does not support expressions in indexes so the ExpIndex property has been removed.

Constraints Property

ConstraintCallback Method

ConstraintsDisabled Method

DisableContraints Method

EnableConstraints Method	DBISAM does not support constraints so theses properties and methods have been removed.

IndexFiles Property

OpenIndexFile Method

CloseIndexFile Method	DBISAM does not support specifying an external index file for use with a TTable so the properties and methods listed have been removed.

OnServerYield Event	DBISAM is not a client-server database system so the OnServerYield event has been removed.

RestructureFieldDefs Property	This public runtime property, which is of the type TRestructureFieldDefs, is used to define data file restructure parameters for individual fields.  This property is very similar to the normal TTable FieldDefs property, the only difference in it's usage is that each TRestructureFieldDef object contained in the RestructureFieldDefs list contains different properties that specify instructions on how to restructure a data file's field definitions.  The following is the list of properties in each TRestructureFieldDef and their meaning:

Property	Notes

DataType	The DataType property is of the type TFieldType and is used to indicate the data type for the field.  Please see the Delphi help for more information on the TFieldType type.

FieldNo	The FieldNo property is of the type Integer and is used to indicate the field position in the restructure process.  This property is very important as you will see later in the example restructure code.  Please note that the FieldNo property is 1-based, not 0-based, just like the normal FieldNo property.

Name	The Name property is of the type String and is used to indicate the field name.

Required	The Required property is of the type Boolean and is used to indicate whether a field is required (cannot be NULL) or not.

Size	The Size property is of the type Word and is used to indicate the size of the field.  This property will only be not equal to 0 for string fields, byte fields, and BCD fields.

DefaultValue	The DefaultValue property is of the type String and is used to indicate the default value for the field. The default value provided in this property must be appropriate for the data type of the field.

Description	The Description property is of the type String and is used to indicate the description of the field.

MinValue	The MinValue property is of the type String and is used to indicate the minimum value allowed for the field. The minimum value provided in this property must be appropriate for the data type of the field.

MaxValue	The MaxValue property is of the type String and is used to indicate the maximum value allowed for the field. The maximum value provided in this property must be appropriate for the data type of the field.

Please see the RestructureTable method below for an example on using the RestructureFieldDefs property when restructuring a data file.

Description Property	This public runtime property is of the type String and indicates the description of the current data file.  This property is read-only, you must restructure a data file in order to change it's description.

LastUpdated Property	This public runtime property is of the type TDateTime and indicates the last time the current data file was updated.  This property is read-only is automatically maintained by DBISAM for each data file.

CopyTable Method	This public method is used to copy an existing data file to a new data file.  This method accepts one parameter - the name of the data file to copy to.  The following is an example of using the CopyTable method to copy a data file:

with DBISAMTable1 do

  begin

  Active:=False;

  DatabaseName:='C:\MYDATA';

  TableName:='CUSTOMER.DAT';

  CopyTable('C:\MYDATA\BACKUP\CUSTOMER.DAT');

  end;

RepairTable Method	This public method is used to repair an existing data file that has been corrupted.  This method has no parameters.  The following is an example of using the RepairTable method to repair a data file:

with DBISAMTable1 do

  begin

  Active:=False;

  DatabaseName:='C:\MYDATA';

  TableName:='CUSTOMER.DAT';

  RepairTable;

  end;

You can use the OnRepairProgress event described below to display the progress of the repair to the user of your application.

RestructureTable Method	This public method is used to restructure an existing data file. This method accepts four parameters:

Parameter	Notes

NewEncrypted

(Boolean)	The new encrypted flag, if True then the data file will be encrypted, if False then the data file will not be encrypted.

NewPassword

(String)	The new password string, this only applies if the NewEncrypted parameter is True.  If the NewEncrypted parameters if False then this parameter will be ignored. The password string cannot be blank and cannot be more than 15 characters in length.

NewDescription

(String)	The new description of the data file to being restructured.

NewBlobBlockSize

(Word)	The new BLOB block size of the data file to being restructured.  This value may be between 64 bytes and 64k (65535 bytes).

The following is an example of using the RestructureFieldDefs property, the RestructureTable method, and the OnRestructureProgress and OnDataLost events (all found only in the TDBISAMTable component) to restructure a data file in code.

For this example we'll assume an existing data file called CUSTOMER.DAT that contains the following structure:

Attribute	Current Value

Data File Description	(blank)

Field 1	Name: CustomerNo

DataType: Integer

FieldNo: 1

Validity Checks: (none)

Field 2	Name: CompanyName

DataType: String(30)

FieldNo: 2

Validity Checks: (none)

Field 3	Name: LastOrderDate

DataType: Date

FieldNo: 3

Validity Checks: (none)

Field 4	Name: CreditLimit

DataType: BCD(2)

FieldNo: 4

Validity Checks: (none)

Primary Index	Fields: CustomerNo

Descending: No

Case-Insensitive: No

Now what we wish to do is restructure the data file so that it looks like the following:

Attribute	New Value

Data File Description	Customer Information

Field 1	Name: CustomerNo

DataType: Integer

FieldNo: 1

Validity Checks: Required (not NULL)

Field 2	Name: ContactName

DataType: String(30)

FieldNo: 5

Validity Checks: (none)

Field 3	Name: CompanyName

DataType: String(30)

FieldNo: 2

Validity Checks: Required (not NULL)

Field 4	Name: LastOrderDate

DataType: Date

FieldNo: 3

Validity Checks: (none)

Field 5	Name: CreditLimit

DataType: BCD(2)

FieldNo: 4

Validity Checks: MinValue (> 0)

Primary Index	Fields: CustomerNo

Descending: No

Case-Insensitive: No

Secondary Index	Fields: CompanyName

Descending: No

Case-Insensitive: Yes

As you can see, what we want to do is:

 	Add a new field called ContactName after the CustomerNo field

 	Make the existing CustomerNo field be required

 	Make the existing CompanyName field be required

 	Make the existing CreditLimit field be required to be greater than 0

 	Add a new case-insensitive secondary index called CompanyName consisting of the CompanyName field

Please note that field numbers are always 1-based, not 0-based.  This is very important to remember when restructuring data files.

The following code will restructure our example CUSTOMER.DAT data file so that it looks like we want.

with DBISAMTable1 do

  begin

  with RestructureFieldDefs do

    begin

    Clear;

    Add('CustomerNo',ftInteger,0,True,'','','','',1);

    Add('ContactName',ftString,30,False,'','','','',5);

    Add('CompanyName',ftString,30,True,'','','','',2);

    Add('LastOrderDate',ftDate,0,False,'','','','',3);

    Add('CreditLimit',ftBCD,2,False,'','0','','',4);

    end;

  with IndexDefs do

    begin

    Clear;

    Add('','CustomerNo',[ixPrimary]);

    Add('CompanyName','CompanyName'[ixCaseInsensitive]);

    end;

  RestructureTable(False,'','Customer Information',512);

end;

You can use the OnRestructureProgress event described below to display the progress of the restructure to the user of your application and you can use the OnDataLost event described below to deal with the possibility of data loss during the restructure process.

FlushBuffers Method	This public method is used to flush the data buffers of a data file that has been opened exclusively. This method has no parameters.  Normally a data file opened exclusively only flushes it's buffers to disk when absolutely necessary or when the data file is closed.  Using this method at key points in your application on a data file that has been opened exclusively will help prevent data loss and corruption in the case of an unexpected application termination like a power loss.

TableIsLocked Method	This public method is used to determine if the current data file has been locked using the LockTable method.  This method simply returns True if the current data file is locked, and False if it is not.  Please note, this method only looks at whether the current application has locked the current data file, not if other applications have locked the current data file.

RecordIsLocked Method	This public method is used to determine if the current record in the current data file has been locked using the Edit method.  This method simply returns True if the current record is locked, and False if it is not.  Please note, this method only looks at whether the current application has locked the current record, not if other applications have locked the current record.

InMemory Property	This published Boolean property is used to indicate whether you wish the current data file to be an in-memory data file or a disk-based data file.  Setting this property to True will cause DBISAM to treat the current data file entirely in memory.  DBISAM in-memory data files behave exactly like disk-based data files except for one small difference - you cannot place locks on in-memory data files or the records contained in them.  You must first create the data file using the CreateTable method and then delete it using the DeleteTable.  What this means is that you cannot open an in-memory data in design mode in the IDE.

The following is an example of using the InMemory property, the CreateTable method, and the DeleteTable method to create an in-memory data file, perform some operations, and then delete the data file:

with DBISAMTable1 do

  begin

  DatabaseName:='';

  TableName:='MEMCUST.DAT';

  InMemory:=True;

  with FieldDefs do

    begin

    Clear;

    Add('CustomerNo',ftInteger,0,True);

    Add('ContactName',ftString,30,False);

    Add('CompanyName',ftString,30,True);

    Add('LastOrderDate',ftDate,0,False);

    Add('CreditLimit',ftBCD,2,False);

    end;

  with IndexDefs do

    begin

    Clear;

    Add('','CustomerNo',[ixPrimary]);

    end;

  CreateTable;

  try

    { Perform some operations on the data file }

  finally

    DeleteTable;

  end;

end;

SaveToStream Method

LoadFromStream Method	These public methods are used to load and save the current in-memory data file to and from a stream (any TStream descendant).  These methods are only valid when dealing with in-memory data files (InMemory property should be True) and will be ignored for disk-based data files.  Please see the sample project MEMBLOB.DPR in the SAMPLES sub-directory under the main DBISAM install directory for an example of using the SaveToStream and LoadFrom Stream methods to implement embedded sub-tables inside of a single record.

OnRepairProgress Event	This published event is used to handle progress notification during a RepairTable method call.  There are three parameters passed to the event:

Event Parameter	Notes

Sender	This TObject parameter will be the current TTable or TDBISAMTable executing the RepairTable method.

CurrentRecord	This Longint parameter indicates the current record being repaired in the data file.

PercentDone	This Word parameter indicates the current percentage of completion for the RepairTable operation.

OnIndexProgress Event	This published event is used to handle progress notification during an AddIndex or DeleteIndex method call.  There are three parameters passed to the event:

Event Parameter	Notes

Sender	This TObject parameter will be the current TTable or TDBISAMTable executing the AddIndex or DeleteIndex method.

CurrentRecord	This Longint parameter indicates the current record being added or deleted from the available indexes in the data file.

PercentDone	This Word parameter indicates the current percentage of completion for the AddIndex or DeleteIndex operation.

OnRestructureProgress Event	This published event is used to handle progress notification during a RestructureTable method call.  There are three parameters passed to the event:

Event Parameter	Notes

Sender	This TObject parameter will be the current TTable or TDBISAMTable executing the RestructureTable method.

CurrentRecord	This Longint parameter indicates the current record being restructured in the data file.

PercentDone	This Word parameter indicates the current percentage of completion for the RestructureTable operation.

 OnDataLost Event	This published event is used to handle data loss during a RestructureTable method call.  There are three parameters passed to the event:

Event Parameter	Notes

Sender	This TObject parameter will be the current TTable or TDBISAMTable executing the RestructureTable method.

Cause	This TDataLossCause parameter indicates the current cause for the potential data loss.  The TDataLossCause parameter can be one of the following:

 dlUnknown

DBISAM cannot determine why data loss is occurring, this should never occur.

 dlKeyViolation

DBISAM has encounterd a key violation due most likely to a modification to the definition of the primary index fields in the current data file.

 dlValidityCheckFail

DBISAM has encountered a validity check (Required, Min/Max) failure due most likely to the addition of a new validity check constraint.

 dlFieldDeletion

DBISAM has encountered data loss due to a field deletion.

 dlFieldConversion

DBISAM has encountered data loss due to an unmanageable field conversion, such as a conversion from a BLOB field to a TimeStamp field.

ContinueRestructure	This variable Boolean parameter can be used to indicate to DBISAM whether the current restructure operation should be continued, even with the data loss, or aborted with the data file returned to it's pre-restructure state.

StopAsking	This variable Boolean parameter can be used to indicate to DBISAM whether it should stop making OnDataLost event calls and ignore any future data loss during the restructure operation.

TransactionsInMemory Property	This published Boolean property is used to determine whether the current data file should process all transactions in an in-memory transaction log or use a disk-based transaction log.  If performance is especially critical during transactions then you should set this property to True.

LockRetryCount Property	This published Byte property is used to determine the number of lock retries attempted when a record or file lock attempt fails.  The default value is 15 retries.  You should increase this figure if your multi-user network is especially busy and you start to receive lock failure exceptions.

LockWaitTime Property	This published Word property is used to determine the amount of time, in milliseconds, between lock retries when a record or file lock attempt fails.  The default value is 100 milliseconds.  You should increase this figure if your multi-user network is especially busy and you start to receive lock failure exceptions.

FilterOptimizeLevel	This public property of type TOptimizeLevel indicates whether the current expression filter specified in the Filter property is either not optimizable (olNone), partially optimizable (olPartial), or fully optimizable (olFull). If the Filter property is empty or the data file is closed this property will contain the value olNone.

Encrypted	This public Boolean property indicates whether the current data file is encrypted or not. If the current data file is closed this property will contain False.

Password	This public string property indicates the password for the current data file if the data file is encrypted.  If the current data file is closed or not encrypted then this property will contain a blank string.


Error Messages and Error Handling

An important thing to note is that in the Delphi 3.0x and 4.0x support and above DBISAM uses it's own error class type TDBISAMError, not the standard TDBError class type.  Also, database engine errors in the DBISAM Delphi 3.0x and 4.0x support and above use the EDBISAMEngineError exception type, not the standard EDBEngineError exception type.  However, the behavior between the classes and exception types is identical, only the naming conventions differ.

The following is a table of the error messages generated by the DBISAM database engine, their corresponding error codes and constants used by DBISAM to represent them, and links to more information about the error.  Please keep in mind that this list only covers the errors issued by the DBISAM database engine itself and does not cover general database errors issued by the interface units. For a listing of those errors please consult the Delphi help files for the appropriate version of Delphi that you are using.  DBISAM uses the same errors as Delphi for all versions.  Also, all of the error codes listed below have a direct corresponding error code with the same number in the BDE.  This is to ensure that error codes do not differ between the BDE and DBISAM, causing the programmer to code error handling specifically for one database engine or the other.  If you wish to use the error constants defined by DBISAM in your applications for error trapping you need to make sure that the DBBASE.DCU file is included in your USES clause.  All of the error constants for DBISAM are stored in the DBBASE.DCU file.  The following is an example (Delphi 3 using the TDBISAMTable component) of trapping for a record lock exception using the constants provided with DBISAM and allowing the user to retry the operation:

uses DBISAMTb, DBBase, Dialogs;

function EditRecord(TableToEdit: TDBISAMTable): Boolean;

begin

  while True do

    begin

    Result:=False;

    try

      TableToEdit.Edit;

      Result:=True;

      Break;

    except

      on E: Exception do

        begin

        if (E is EDatabaseError) and (E is EDBISAMEngineError) then

          begin

          if (EDBISAMEngineError(E).Errors[0].ErrorCode=DBISAM_RECLOCKFAILED) then

            begin

            if (MessageDlg('This record is currently locked by '+

                           'another user, would you like to try '+

                           'to edit this record again ?',mtConfirmation,

                           [mbYes,mbNo],0)=mrNo) then

              Break;

            end

          else

            begin

            MessageDlg('Error editing record',mtError,[mbOk],0);

            Break;

            end;

          end

        else

          begin

          MessageDlg('Error editing record',mtError,[mbOk],0);

          Break;

          end;

        end;

    end;

    end;

end;

Error # and Constant	Error Message and Further Information

# 8705

DBISAM_BOF	Beginning of file encountered in data file <ErrorFileName>

This error should not normally occur since encountering the beginning of file in a data file is a normal occurrence.  The only time this error is triggered is when the beginning of file is encountered unexpectedly.

# 8706

DBISAM_EOF	End of file encountered in data file <ErrorFileName>

This error should not normally occur since encountering the end of file in a data file is a normal occurrence.  The only time this error is triggered is when the end of file is encountered unexpectedly.

# 8708

DBISAM_KEYORRECDELETED	Key not found in data file <ErrorFileName>

This error occurs when the database engine attempts to update or delete an index key entry from the data file and fails to find the desired index key entry.  The usual cause of this is either a malfunction in the database engine (in which case you should immediately contact Elevate Software for information on how to proceed with resolving the problem) or from a corrupt index (in which case you should use the DBSYS.EXE Database System Utility to repair the data file).

# 8710

DBISAM_RECNOTFOUND	Record not found in in data file <ErrorFileName>

This error occurs when a call to the GotoCurrent method of the TTable and TDBISAMTable components fails to find the corresponding record in the passed destination table.  Please see the Delphi online help for more information on the GotoCurrent method and it's restrictions.

# 8711

DBISAM_ENDOFBLOB	End of blob data in data file <ErrorFileName> reached prematurely

This error occurs when the DBISAM database engine expects a blob entry to be x number of bytes in length but encounters the end of the data before reaching the desired number of bytes.  The most likely cause of this error is corruption in the data file (in which case you should use the DBSYS.EXE Database System Utility to repair the data file).

# 8962

DBISAM_FILECORRUPT	Record buffers corrupt in data file <ErrorFileName>

This error occurs when the DBISAM database engine attempts to allocate a record in the internal caching mechanism and receives a nil buffer in return.  This error should never occur, however if it does the most likely reason is an extreme shortage of available memory in Windows.   As a precaution, you should use the DBSYS.EXE Database System Utility to repair the data file if this error occurs.

# 8963

DBISAM_MEMOCORRUPT	Block buffers corrupt in data file <ErrorFileName>

This error occurs when the DBISAM database engine attempts to allocate a blob block in the internal caching mechanism and receives a nil buffer in return.  This error should never occur, however if it does the most likely reason is an extreme shortage of available memory in Windows.   As a precaution, you should use the DBSYS.EXE Database System Utility to repair the data file if this error occurs.

# 8965

DBISAM_INDEXCORRUPT	Page buffers corrupt in data file <ErrorFileName>

This error occurs when the DBISAM database engine attempts to allocate an index page in the internal caching mechanism and receives a nil buffer in return.  This error should never occur, however if it does the most likely reason is an extreme shortage of available memory in Windows.   As a precaution, you should use the DBSYS.EXE Database System Utility to repair the data file if this error occurs.

# 9217

DBISAM_READERR	Error reading from data file <ErrorFileName>

This error occurs when the DBISAM database engine attempts to read from the data file and cannot read the desired number of bytes.  This error should never occur, however if it does the most likely reason is corruption in the file that has mangled internal pointers so that they point beyond the end of the file.  You should use the DBSYS.EXE Database System Utility to repair the data file if this error occurs.

# 9218

DBISAM_WRITEERR	Error writing to data file <ErrorFileName>

This error occurs when the DBISAM database engine attempts to write to the data file and cannot write the desired number of bytes.  This error should never occur, however if it does the most likely reason is corruption in the file that has mangled internal pointers so that they point beyond the end of the file.  You should use the DBSYS.EXE Database System Utility to repair the data file if this error occurs.

# 9220

DBISAM_FILEDELETEFAIL	Cannot delete data file <ErrorFileName>

This occurs when the DBISAM database engine attempts to delete a data file and cannot delete one of the files due to the file being marked as read-only, improper network rights, or some other operating system issue.

# 9221

DBISAM_FILENOACCESS	Error accessing file header information for data file <ErrorFileName>

This error occurs when the DBISAM database engine attempts to lock the header of the data file and the lock fails.  The database engine attempts to lock the header when adding, updating, or deleting records so this is a very common operation.  The most likely cause of this error is multi-user concurrency issues with the number of users.  If you receive this error you should immediately contact Elevate Software for more information on how to resolve this issue.

# 9477

DBISAM_RECTOOBIG	Maximum record size exceeded in data file <ErrorFileName>

This error occurs when an attempt is made to create a new data file or restructure an existing data file and doing so would exceed the maximum allowable record size. If you receive this error you should consult the System Capacities topic for more information on the limits for record sizes.

# 9487

DBISAM_INDEXLIMIT	Maximum or minimum limits on number of indexes or fields in an index exceeded in data file <ErrorFileName>

This error occurs when an attempt is made to add a new secondary index or create a new data file and doing so would exceed the maximum number of indexes or the maximum number of fields per index that can be present in a data file.  If you receive this error you should consult the System Capacities topic for more information on the limits for indexes.

# 9492

DBISAM_FLDLIMIT	Maximum or minimum limits on number of fields or field size exceeded in data file <ErrorFileName>

This error occurs when an attempt is made to create a new data file and doing so would exceed the maximum number of fields or the maximum field size that can be present in a data file.  If you receive this error you should consult the System Capacities topic for more information on the limits for fields.

# 9494

DBISAM_OPENBLOBLIMIT	Too many blobs opened in data file <ErrorFileName>

This error occurs when DBISAM internally attempts to open more blobs than allowed.  This error should never occur so if it does you should contact Elevate Software immediately for a resolution to the problem.

# 9498

DBISAM_BLOBLIMIT	Too many blob fields or invalid blob block size specified for data file <ErrorFileName>

This error occurs when an attempt is made to create a new data file and doing so would exceed the maximum number of blob fields that can be present in a data file or the valid range of blob block sizes.  If you receive this error you should consult the System Capacities topic for more information on the limits for the number of blob fields or the blob block size settings.

# 9729

DBISAM_KEYVIOL	Duplicate key found in data file <ErrorFileName>

This is a non-fatal error that occurs when an attempt is made to add a record to a data file and the record would cause a duplicate key to be added for the primary index or for a secondary index that it is defined as being unique.  Primary indexes implicitly enforce uniqueness and therefore cannot permit duplicates to be added, while secondary indexes must be explicitly defined as unique.

# 9730

DBISAM_MINVALERR	Minimum value exceeded for field <ErrorFieldName>

This is a non-fatal error that occurs when an attempt is made to add a record to a data file and a field in the record would violate a minimum value validity check for that field.  Validity checks ensure that data is either present or within an approved range of values for any given field.

# 9731

DBISAM_MAXVALERR	Maximum value exceeded for field <ErrorFieldName>

This is a non-fatal error that occurs when an attempt is made to add a record to a data file and a field in the record would violate a maximum value validity check for that field.  Validity checks ensure that data is either present or within an approved range of values for any given field.

# 9732

DBISAM_REQDERR	You must provide a value for the field <ErrorFieldName>

This is a non-fatal error that occurs when an attempt is made to add a record to a data file and a field in the record would violate a required value validity check for that field.  Validity checks ensure that data is either present or within an approved range of values for any given field.

# 9985

DBISAM_OUTOFRANGE	Invalid field number specified for data file <ErrorFileName>

This error occurs when a field number is referenced in an index or internally within DBISAM and that field number does not exist.  This error should never occur so if it does you should contact Elevate Software immediately for a resolution to the problem.

# 9993

DBISAM_PRIMARYKEYREDEFINE	Primary index is already defined and cannot be added again

This error occurs when an attempt is made to add a primary index to a data file when one already exists.  All DBISAM data files require a primary index so the only way to modify the primary index for a data file is to create a new data file or restructure an existing data file and change the primary index fields.

# 9998

DBISAM_INVALIDBLOBOFFSET	Invalid blob offset into data file <ErrorFileName> specified

This error occurs when the DBISAM database engine attempts to access blob data in a data file and the offset at which it is trying to access the data is invalid.  This error should never occur, however if it does the most likely reason is corruption in the file that has mangled internal pointers so that they point beyond the end of the file or are 0.  You should use the DBSYS.EXE Database System Utility to repair the data file if this error occurs.

# 10000

DBISAM_INVALIDFLDTYPE	Invalid field definition specified for field <ErrorFieldName>

This error occurs when an attempt is made to create a new data file or restructure and existing data file and a field definition is invalid due to a bad field type or a length that exceeds the maximum limits for fields.  If you receive this error you should consult the System Capacities topic for more information on the limits for the length of fields.

# 10006

DBISAM_INVALIDVCHKSTRUCT	Invalid default, min, or max validity check specified for <ErrorFieldName>

This error occurs when a default value, minimum check, or maximum check expression for the indicated field is invalid.  You need to verify that the expression provided is appropriate for the data type of the indicated field.

# 10010

DBISAM_INDEXNAMEREQUIRED	Secondary index name missing or not specified

This error occurs when an attempt is made to add a new secondary index and the secondary index name is missing or not specified.  All secondary indexes require a unique name that is used to identify the index.

# 10015

DBISAM_INVALIDPASSWORD	Password provided for data file <ErrorFileName> is either blank or too long

This error occurs when an attempt is made to create or restucture a data file and add encryption with an invalid password.  Passwords for encryption cannot be blank and must be less than or equal to 15 characters in length.

# 10022

DBISAM_INVALIDINDEXNAME	Invalid secondary index name <ErrorIndexName>  specified

This error occurs when an attempt is made to delete a secondary index and the index name specified for deletion does not exist.

# 10026

DBISAM_INVALIDKEY	Invalid key size specified for index <ErrorIndexName>

This error occurs when an attempt is made to add a new secondary index or create a new data file and doing so would exceed the maximum length of an index key that can be present in a data file.  If you receive this error you should consult the System Capacities topic for more information on the limits for indexes.

# 10027

DBISAM_INDEXEXISTS	Secondary index <ErrorIndexName> already exists

This error occurs when an attempt is made to add a new secondary index and the secondary index name already exists in the data file.  All secondary indexes require a unique name that is used to identify the index.

# 10029

DBISAM_INVALIDBLOBLEN	Invalid blob length in data file <ErrorFileName>

This error occurs when the DBISAM database engine attempts to access blob data in the data file and the length of the blob data it is trying to access is invalid.  This error should never occur, however if it does the most likely reason is corruption in the file that has mangled internal pointers so that they point beyond the end of the file or are 0.  You should use the DBSYS.EXE Database System Utility to repair the data file if this error occurs.

# 10030

DBISAM_INVALIDBLOBHANDLE	Invalid blob handle for data file <ErrorFileName> specified

This error occurs when the Data Access Components or DBISAM internally attempt to modify an open blob with an invalid handle to the open blob.  This error should never occur so if it does you should contact Elevate Software immediately for a resolution to the problem.

# 10031

DBISAM_TABLEOPEN	Data file is already in use <ErrorFileName>

This error occurs when an attempt is made to perform an operation on a data file that requires the data file to be closed in order to complete the operation.  The operations that require the data file to be closed are as follows:

 	Repairing a data file

 	Restructuring a data file

# 10038

DBISAM_INVALIDFIELDNAME	Invalid or duplicate field name <ErrorFieldName> specified

This error occurs when an attempt is made to define the specified field with an invalid or duplicate field name.  An example of an invalid field name is a blank field name or a field name that starts with an invalid character such as a digit.

# 10050

DBISAM_NOSUCHFILTER	Invalid filter handle specified

This error occurs when an attempt is made by the data access components to refer to a filter expression or callback filter that does not exist.  This error should never occur so if it does you should contact Elevate Software immediately for a resolution to the problem.

# 10051

DBISAM_INVALIDFILTER	Invalid filter expression specified

This error should never occur so if it does you should contact Elevate Software immediately for a resolution to the problem.

# 10055

DBISAM_INVALIDINDEXDELETE	Primary index cannot be removed

This error occurs when an attempt is made to delete the primary index from a data file.  All DBISAM data files require a primary index.

# 10241

DBISAM_LOCKED	Data file is already locked by another user <ErrorFileName>

This error occurs when an attempt is made to lock a data file that is already locked by another application or the same application.  This error will also occur if an attempt is made to lock a data file and there are individual record(s) locked in the data file.

# 10242

DBISAM_UNLOCKFAILED	Cannot unlock data file or record in data file <ErrorFileName>

This error occurs when DBISAM cannot unlock a record in a data file or the entire data file itself.  This error should never occur so if it does you should contact Elevate Software immediately for a resolution to the problem.

# 10253

DBISAM_NEEDEXCLACCESS	Data file <ErrorFileName> must be opened exclusively

This error occurs when an attempt is made to perform an operation on a data file that requires the data file to be opened exclusively in order to complete the operation.  The operations that require exclusive use of the data file are as follows:

Creating a data file

Emptying a data file

Repairing a data file

Adding a secondary index to a data file

Deleting a secondary index from a data file

Restructuring a data file

# 10258

DBISAM_RECLOCKFAILED	Record in data file <ErrorFileName> is in use by another user

This error occurs when an attempt is made to lock a record in a data file that is already locked by another application or the same application.

# 10498

DBISAM_NOTSUFFTABLERIGHTS	Insufficient rights to data file <ErrorFileName>, password is required

This error occurs when an attempt is made to perform an operation on an encrypted data file and a valid password has not been provided.  You can add new passwords for the current session using the OnPassword event or AddPassword method of the TSession or TDBISAMSession component.

# 10753

DBISAM_NOTABLOB	Invalid blob field <ErrorFieldName> specified for data file

This error occurs when an attempt is made by the Data Access Components or DBISAM internally to perform a blob operation on a field that is not a blob field.  This error should never occur so if it does you should contact Elevate Software immediately for a resolution to the problem.

# 11010

DBISAM_OSENOENT	Invalid path or file name for data file <ErrorFileName>

This error occurs when an attempt is made to open up a data file that does not exist.

# 11012

DBISAM_OSEMFILE	Too many files open attempting to open data file <ErrorFileName>

This error occurs when an attempt is made to open up a data file and the operating system rejects the open because it has run out of available file handles.   If you receive this error you should consult the System Capacities topic for more information on the limits for the number of open data files.

# 11013

DBISAM_OSEACCES	Access denied to data file <ErrorFileName>

This error occurs when an attempt is made to open up a data file that has already been opened up exclusively by another application or the same application.  A data file can be opened exclusively only once.

# 11014

DBISAM_OSEBADF	Invalid file handle for data file <ErrorFileName>

This error occurs when DBISAM internally attempts to perform an operation on a data file using an invalid file handle.  This error should never occur so if it does you should contact Elevate Software immediately for a resolution to the problem.

# 11016

DBISAM_OSENOMEM	Insufficient memory present for data file <ErrorFileName>

This error occurs when there is insufficient memory for the operating system to open or create a data file.  This error should never occur so if it does you should contact Elevate Software immediately for a resolution to the problem.

# 11017

DBISAM_OSEINVMEM	Invalid length for in-memory data file <ErrorFileName>

This error only occurs when using the 16-bit version of DBISAM under Delphi 1.02, and is caused when the size of an in-memory data file exceeds the 64k segment size imposed by the 16-bit environment.  This error will never occur under Delphi 2.01 and above.  If you encounter this error the only workaround is to convert your usage of in-memory data files to temporary data files on disk.

# 11025

DBISAM_OSENOTSAM	Data file <ErrorFileName> has been moved

This error occurs when the operating system detects that a file has been moved from one device to another after being opened.  This error should essentially never occur.

# 11047

DBISAM_OSUNKNOWN	Unknown error occurred with data file <ErrorFileName>

This error occurs when DBISAM detects an error but cannot identify it.  Examples of this may include operating system errors that DBISAM does not specifically identify.  If you receive this error you should contact Elevate Software immediately for a resolution to the problem.

# 12035

DBISAM_OLDVERSION	Incorrect version for data file <ErrorFileName>

This error occurs when an attempt is made to open a data file that is either the incorrect version for DBISAM or is not a DBISAM data file at all (but may have the same extension of .DAT).

# 12292

DBISAM_SEARCHCOLREQD	Invalid field type specified in index <ErrorIndexName>

This error occurs when an attempt is made to add a secondary index or create a data file with a primary index that contains blob fields as one or more of the index fields.  Blob fields cannot be directly indexed in DBISAM.


System Capacities

The following is a detailed list of the capacities for the different components in the DBISAM Database System.  Unless where noted all capacities are absolute and not dependent upon the underlying operating system or network.

Capacity	Details

# of Open Data Files	Only limited by available memory and open file handles.  DBISAM uses a maximum of 3 file handles per data file: one for the data file, one for the index file, and one for the blob file (if there are blob fields present in the data file).  Additional file handles are temporarily used for transactions, and are equivalent to the source data file where the transaction is taking place.  For example, if you have a data file using 3 file handles, then any transactions started on this data file will cause a similar data file to created and opened for logging transactions and will consume another 3 file handles.

# of Records Per Data File	Maximum number of records that can be added to a data file is 1 billion.   This figure normally is not reached before bypassing the 2 gigabyte file size limitation imposed by some operating systems such as DOS/Windows 3.1 and Windows 95.  Please check your operating system or network operating system manual for more information on the maximum file size allowed.

# of Records in a Transaction	Restricted to the same constraints for the number of records allowed in a data file listed above.

Record Size	Maximum record size is 64k

# of Fields	Maximum number of fields in a data file is 512.

Length of a String Field	Maximum length of a string field is 245 bytes.  Please note that this figure does not include a NULL terminator character.  The NULL terminator character is handled internally.

# of Decimal Places for BCD Fields	Maximum number of decimals places for BCD fields is 4.

# of Indexes	Maximum number of primary indexes is 1. Maximum number of secondary indexes is 30.

# of Fields in Index Key	Maximum number of fields that can be present in an index key is 16.

Length of Index Key	Maximum length of an index key is 254 bytes.  Please note that the index key length is not an exact sum of the length of the fields present in the index key.  The proper way to calculate the index key length is as follows:

Type of Index Key	Formula

Primary Index	((Sum of field sizes) + Number of Fields in Index Key

The extra bytes for the number of fields are the NULL flags used to order the index keys properly based upon whether they are NULL or not.

Secondary Index	((Sum of field sizes) + Number of Fields in Index Key + 4

The additional four bytes for secondary indexes is used to store a unique record ID which is essential for proper bookmark support.

Please note that the length of string fields in index keys includes the null terminator character.  For example, if a string field has a length of 15 then it's length in an index key would be 16.

# of Blob Fields Per Data File	Maximum number of blob fields per data file is 32.

# of Open Blobs Per Data File	Maximum number of open blobs per data file is 64.  You should never have to worry about this figure because the DBISAM Data Access Components handle opening and closing blobs automatically.

Length of Blob Data	Maximum length of blob data in a blob field is 64k for Delphi 1.02 and only limited by available memory for Delphi 2.01, 3.0x, and 4.0x.

Blob block size	The minimum blob block size is 64 bytes and the maximum blob block size is 64k.

Size of In-Memory Data File	Maximum length of an in-memory data file, index file, or blob file is 64k for Delphi 1.02 and only limited by available memory for Delphi 2.01, 3.0x, and 4.0x.


Delphi 1 TDBISAMTable Component
Differences Between Delphi/BDE and Delphi/DBISAM in Delphi 1

TDBISAMTable Component

The following is a listing of the properties and methods in the TDBISAMTable component that have been added and notes about the behavior of the additions:

Property, Method, or Event	Notes

RestructureFieldDefs Property	This public runtime property, which is of the type TRestructureFieldDefs, is used to define data file restructure parameters for individual fields.  This property is very similar to the normal TTable FieldDefs property, the only difference in it's usage is that each TRestructureFieldDef object contained in the RestructureFieldDefs list contains different properties that specify instructions on how to restructure a data file's field definitions.  The following is the list of properties in each TRestructureFieldDef and their meaning:

Property	Notes

DataType	The DataType property is of the type TFieldType and is used to indicate the data type for the field.  Please see the Delphi help for more information on the TFieldType type.

FieldNo	The FieldNo property is of the type Integer and is used to indicate the field position in the restructure process.  This property is very important as you will see later in the example restructure code.  Please note that the FieldNo property is 1-based, not 0-based, just like the normal FieldNo property.

Name	The Name property is of the type String and is used to indicate the field name.

Required	The Required property is of the type Boolean and is used to indicate whether a field is required (cannot be NULL) or not.

Size	The Size property is of the type Word and is used to indicate the size of the field.  This property will only be not equal to 0 for string fields, byte fields, and BCD fields.

DefaultValue	The DefaultValue property is of the type String and is used to indicate the default value for the field. The default value provided in this property must be appropriate for the data type of the field.

Description	The Description property is of the type String and is used to indicate the description of the field.

MinValue	The MinValue property is of the type String and is used to indicate the minimum value allowed for the field. The minimum value provided in this property must be appropriate for the data type of the field.

MaxValue	The MaxValue property is of the type String and is used to indicate the maximum value allowed for the field. The maximum value provided in this property must be appropriate for the data type of the field.

Please see the RestructureTable method below for an example on using the RestructureFieldDefs property when restructuring a data file.

Description Property	This public runtime property is of the type String and indicates the description of the current data file.  This property is read-only, you must restructure a data file in order to change it's description.

LastUpdated Property	This public runtime property is of the type TDateTime and indicates the last time the current data file was updated.  This property is read-only is automatically maintained by DBISAM for each data file.

RecNo Property	This public runtime property is of the type Longint and indicates the current record number in the current data file.  Modifying this property causes the current record position in the data file to change to the desired record number.

CopyTable Method	This public method is used to copy an existing data file to a new data file.  This method accepts one parameter - the name of the data file to copy to.  The following is an example of using the CopyTable method to copy a data file:

with DBISAMTable1 do

  begin

  Active:=False;

  DatabaseName:='C:\MYDATA';

  TableName:='CUSTOMER.DAT';

  CopyTable('C:\MYDATA\BACKUP\CUSTOMER.DAT');

  end;

RepairTable Method	This public method is used to repair an existing data file that has been corrupted.  This method has no parameters.  The following is an example of using the RepairTable method to repair a data file:

with DBISAMTable1 do

  begin

  Active:=False;

  DatabaseName:='C:\MYDATA';

  TableName:='CUSTOMER.DAT';

  RepairTable;

  end;

You can use the OnRepairProgress event described below to display the progress of the repair to the user of your application.

RestructureTable Method	This public method is used to restructure an existing data file. This method accepts four parameters:

Parameter	Notes

NewEncrypted

(Boolean)	The new encrypted flag, if True then the data file will be encrypted, if False then the data file will not be encrypted.

NewPassword

(String)	The new password string, this only applies if the NewEncrypted parameter is True.  If the NewEncrypted parameters if False then this parameter will be ignored. The password string cannot be blank and cannot be more than 15 characters in length.

NewDescription

(String)	The new description of the data file to being restructured.

NewBlobBlockSize

(Word)	The new BLOB block size of the data file to being restructured.  This value may be between 64 bytes and 64k (65535 bytes).

The following is an example of using the RestructureFieldDefs property, the RestructureTable method, and the OnRestructureProgress and OnDataLost events (all found only in the TDBISAMTable component) to restructure a data file in code.

For this example we'll assume an existing data file called CUSTOMER.DAT that contains the following structure:

Attribute	Current Value

Data File Description	(blank)

Field 1	Name: CustomerNo

DataType: Integer

FieldNo: 1

Validity Checks: (none)

Field 2	Name: CompanyName

DataType: String(30)

FieldNo: 2

Validity Checks: (none)

Field 3	Name: LastOrderDate

DataType: Date

FieldNo: 3

Validity Checks: (none)

Field 4	Name: CreditLimit

DataType: BCD(2)

FieldNo: 4

Validity Checks: (none)

Primary Index	Fields: CustomerNo

Descending: No

Case-Insensitive: No

Now what we wish to do is restructure the data file so that it looks like the following:

Attribute	New Value

Data File Description	Customer Information

Field 1	Name: CustomerNo

DataType: Integer

FieldNo: 1

Validity Checks: Required (not NULL)

Field 2	Name: ContactName

DataType: String(30)

FieldNo: 5

Validity Checks: (none)

Field 3	Name: CompanyName

DataType: String(30)

FieldNo: 2

Validity Checks: Required (not NULL)

Field 4	Name: LastOrderDate

DataType: Date

FieldNo: 3

Validity Checks: (none)

Field 5	Name: CreditLimit

DataType: BCD(2)

FieldNo: 4

Validity Checks: MinValue (> 0)

Primary Index	Fields: CustomerNo

Descending: No

Case-Insensitive: No

Secondary Index	Fields: CompanyName

Descending: No

Case-Insensitive: Yes

As you can see, what we want to do is:

 	Add a new field called ContactName after the CustomerNo field

 	Make the existing CustomerNo field be required

 	Make the existing CompanyName field be required

 	Make the existing CreditLimit field be required to be greater than 0

 	Add a new case-insensitive secondary index called CompanyName consisting of the CompanyName field

Please note that field numbers are always 1-based, not 0-based.  This is very important to remember when restructuring data files.

The following code will restructure our example CUSTOMER.DAT data file so that it looks like we want.

with DBISAMTable1 do

  begin

  with RestructureFieldDefs do

    begin

    Clear;

    Add('CustomerNo',ftInteger,0,True,'','','','',1);

    Add('ContactName',ftString,30,False,'','','','',5);

    Add('CompanyName',ftString,30,True,'','','','',2);

    Add('LastOrderDate',ftDate,0,False,'','','','',3);

    Add('CreditLimit',ftBCD,2,False,'','0','','',4);

    end;

  with IndexDefs do

    begin

    Clear;

    Add('','CustomerNo',[ixPrimary]);

    Add('CompanyName','CompanyName'[ixCaseInsensitive]);

    end;

  RestructureTable(False,'','Customer Information',512);

end;

You can use the OnRestructureProgress event described below to display the progress of the restructure to the user of your application and you can use the OnDataLost event described below to deal with the possibility of data loss during the restructure process.

FlushBuffers Method	This public method is used to flush the data buffers of a data file that has been opened exclusive. This method has no parameters.  Normally a data file opened exclusively only flushes it's buffers to disk when absolutely necessary or when the data file is closed.  Using this method at key points in your application on a data file that has been opened exclusively will help prevent data loss and corruption in the case of an unexpected application termination like a power loss.

TableIsLocked Method	This public method is used to determine if the current data file has been locked using the LockTable method.  This method simply returns True if the current data file is locked, and False if it is not.  Please note, this method only looks at whether the current application has locked the current data file, not if other applications have locked the current data file.

RecordIsLocked Method	This public method is used to determine if the current record in the current data file has been locked using the Edit method.  This method simply returns True if the current record is locked, and False if it is not.  Please note, this method only looks at whether the current application has locked the current record, not if other applications have locked the current record.

InMemory Property	This published Boolean property is used to indicate whether you wish the current data file to be an in-memory data file or a disk-based data file.  Setting this property to True will cause DBISAM to treat the current data file entirely in memory.  DBISAM in-memory data files behave exactly like disk-based data files except for one small difference - you cannot place locks on in-memory data files or the records contained in them.  You must first create the data file using the CreateTable method and then delete it using the DeleteTable.  What this means is that you cannot open an in-memory data in design mode in the IDE.

The following is an example of using the InMemory property, the CreateTable method, and the DeleteTable method to create an in-memory data file, perform some operations, and then delete the data file:

with DBISAMTable1 do

  begin

  DatabaseName:='';

  TableName:='MEMCUST.DAT';

  InMemory:=True;

  with FieldDefs do

    begin

    Clear;

    Add('CustomerNo',ftInteger,0,True);

    Add('ContactName',ftString,30,False);

    Add('CompanyName',ftString,30,True);

    Add('LastOrderDate',ftDate,0,False);

    Add('CreditLimit',ftBCD,2,False);

    end;

  with IndexDefs do

    begin

    Clear;

    Add('','CustomerNo',[ixPrimary]);

    end;

  CreateTable;

  try

    { Perform some operations on the data file }

  finally

    DeleteTable;

  end;

end;

SaveToStream Method

LoadFromStream Method	These public methods are used to load and save the current in-memory data file to and from a stream (any TStream descendant).  These methods are only valid when dealing with in-memory data files (InMemory property should be True) and will be ignored for disk-based data files.  Please see the sample project MEMBLOB.DPR in the SAMPLES sub-directory under the main DBISAM install directory for an example of using the SaveToStream and LoadFrom Stream methods to implement embedded sub-tables inside of a single record.

OnRepairProgress Event	This published event is used to handle progress notification during a RepairTable method call.  There are three parameters passed to the event:

Event Parameter	Notes

Sender	This TObject parameter will be the current TTable or TDBISAMTable executing the RepairTable method.

CurrentRecord	This Longint parameter indicates the current record being repaired in the data file.

PercentDone	This Word parameter indicates the current percentage of completion for the RepairTable operation.

OnIndexProgress Event	This published event is used to handle progress notification during an AddIndex or DeleteIndex method call.  There are three parameters passed to the event:

Event Parameter	Notes

Sender	This TObject parameter will be the current TTable or TDBISAMTable executing the AddIndex or DeleteIndex method.

CurrentRecord	This Longint parameter indicates the current record being added or deleted from the available indexes in the data file.

PercentDone	This Word parameter indicates the current percentage of completion for the AddIndex or DeleteIndex operation.

OnRestructureProgress Event	This published event is used to handle progress notification during a RestructureTable method call.  There are three parameters passed to the event:

Event Parameter	Notes

Sender	This TObject parameter will be the current TTable or TDBISAMTable executing the RestructureTable method.

CurrentRecord	This Longint parameter indicates the current record being restructured in the data file.

PercentDone	This Word parameter indicates the current percentage of completion for the RestructureTable operation.

 OnDataLost Event	This published event is used to handle data loss during a RestructureTable method call.  There are three parameters passed to the event:

Event Parameter	Notes

Sender	This TObject parameter will be the current TTable or TDBISAMTable executing the RestructureTable method.

Cause	This TDataLossCause parameter indicates the current cause for the potential data loss.  The TDataLossCause parameter can be one of the following:

 dlUnknown

DBISAM cannot determine why data loss is occurring, this should never occur.

 dlKeyViolation

DBISAM has encounterd a key violation due most likely to the modification to the definition of the primary index fields in the current data file.

 dlValidityCheckFail

DBISAM has encountered a validity check (Required, Min/Max) failure due most likely to the addition of a new validity check constraint.

 dlFieldDeletion

DBISAM has encountered data loss due to a field deletion.

 dlFieldConversion

DBISAM has encountered data loss due to an unmanageable field conversion, such as a conversion from a BLOB field to a TimeStamp field.

ContinueRestructure	This variable Boolean parameter can be used to indicate to DBISAM whether the current restructure operation should be continued, even with the data loss, or aborted with the data file returned to it's pre-restructure state.

StopAsking	This variable Boolean parameter can be used to indicate to DBISAM whether it should stop making OnDataLost event calls and ignore and future data loss during the restructure operation.

TransactionsInMemory Property	This published Boolean property is used to determine whether the current data file should process all transactions in an in-memory transaction log or use a disk-based transaction log.  If performance is especially critical during transactions then you should set this property to True.

LockRetryCount Property	This published Byte property is used to determine the number of lock retries attempted when a record or file lock attempt fails.  The default value is 15 retries.  You should increase this figure if your multi-user network is especially busy and you start to receive lock failure exceptions.

LockWaitTime Property	This published Word property is used to determine the amount of time, in milliseconds, between lock retries when a record or file lock attempt fails.  The default value is 100 milliseconds.  You should increase this figure if your multi-user network is especially busy and you start to receive lock failure exceptions.

Filter Property

FilterOptions Property

Filtered Property

OnFilterRecord Event

FindFirst Method

FindPrior Method

FindNext Method

FindLast Method	These properties, methods, and events have been added to the TDBISAMTable component to bring the filter support in line with that of Delphi 2.01, Delphi 3.x, and Delphi 4.x.  If you have any questions regarding the usage of these properties, methods, and events please refer to the online help for Delphi 2.x, Delphi 3.x, or Delphi 4.x.

FilterOptimizeLevel	This public property of type TOptimizeLevel indicates whether the current expression filter specified in the Filter property is either not optimizable (olNone), partially optimizable (olPartial), or fully optimizable (olFull). If the Filter property is empty or the data file is closed this property will contain the value olNone.

Encrypted	This public Boolean property indicates whether the current data file is encrypted or not. If the current data file is closed this property will contain False;

Password	This public string property indicates the password for the current data file if the data file is encrypted.  If the current data file is closed or not encrypted then this property will contain a blank string.


Delphi 2 TDBISAMTable Component
Differences Between Delphi/BDE and Delphi/DBISAM in Delphi 2

TDBISAMTable Component

The following is a listing of the properties and methods in the TDBISAMTable component that have been added and notes about the behavior of the additions:

Property, Method, or Event	Notes

RestructureFieldDefs Property	This public runtime property, which is of the type TRestructureFieldDefs, is used to define data file restructure parameters for individual fields.  This property is very similar to the normal TTable FieldDefs property, the only difference in it's usage is that each TRestructureFieldDef object contained in the RestructureFieldDefs list contains different properties that specify instructions on how to restructure a data file's field definitions.  The following is the list of properties in each TRestructureFieldDef and their meaning:

Property	Notes

DataType	The DataType property is of the type TFieldType and is used to indicate the data type for the field.  Please see the Delphi help for more information on the TFieldType type.

FieldNo	The FieldNo property is of the type Integer and is used to indicate the field position in the restructure process.  This property is very important as you will see later in the example restructure code.  Please note that the FieldNo property is 1-based, not 0-based, just like the normal FieldNo property.

Name	The Name property is of the type String and is used to indicate the field name.

Required	The Required property is of the type Boolean and is used to indicate whether a field is required (cannot be NULL) or not.

Size	The Size property is of the type Word and is used to indicate the size of the field.  This property will only be not equal to 0 for string fields, byte fields, and BCD fields.

DefaultValue	The DefaultValue property is of the type String and is used to indicate the default value for the field. The default value provided in this property must be appropriate for the data type of the field.

Description	The Description property is of the type String and is used to indicate the description of the field.

MinValue	The MinValue property is of the type String and is used to indicate the minimum value allowed for the field. The minimum value provided in this property must be appropriate for the data type of the field.

MaxValue	The MaxValue property is of the type String and is used to indicate the maximum value allowed for the field. The maximum value provided in this property must be appropriate for the data type of the field.

Please see the RestructureTable method below for an example on using the RestructureFieldDefs property when restructuring a data file.

Description Property	This public runtime property is of the type String and indicates the description of the current data file.  This property is read-only, you must restructure a data file in order to change it's description.

LastUpdated Property	This public runtime property is of the type TDateTime and indicates the last time the current data file was updated.  This property is read-only is automatically maintained by DBISAM for each data file.

RecNo Property	This public runtime property is of the type Longint and indicates the current record number in the current data file.  Modifying this property causes the current record position in the data file to change to the desired record number.

CopyTable Method	This public method is used to copy an existing data file to a new data file.  This method accepts one parameter - the name of the data file to copy to.  The following is an example of using the CopyTable method to copy a data file:

with DBISAMTable1 do

  begin

  Active:=False;

  DatabaseName:='C:\MYDATA';

  TableName:='CUSTOMER.DAT';

  CopyTable('C:\MYDATA\BACKUP\CUSTOMER.DAT');

  end;

RepairTable Method	This public method is used to repair an existing data file that has been corrupted.  This method has no parameters.  The following is an example of using the RepairTable method to repair a data file:

with DBISAMTable1 do

  begin

  Active:=False;

  DatabaseName:='C:\MYDATA';

  TableName:='CUSTOMER.DAT';

  RepairTable;

  end;

You can use the OnRepairProgress event described below to display the progress of the repair to the user of your application.

RestructureTable Method	This public method is used to restructure an existing data file. This method accepts four parameters:

Parameter	Notes

NewEncrypted

(Boolean)	The new encrypted flag, if True then the data file will be encrypted, if False then the data file will not be encrypted.

NewPassword

(String)	The new password string, this only applies if the NewEncrypted parameter is True.  If the NewEncrypted parameters if False then this parameter will be ignored. The password string cannot be blank and cannot be more than 15 characters in length.

NewDescription

(String)	The new description of the data file to being restructured.

The following is an example of using the RestructureFieldDefs property, the RestructureTable method, and the OnRestructureProgress and OnDataLost events (all found only in the TDBISAMTable component) to restructure a data file in code.

For this example we'll assume an existing data file called CUSTOMER.DAT that contains the following structure:

Attribute	Current Value

Data File Description	(blank)

Field 1	Name: CustomerNo

DataType: Integer

FieldNo: 1

Validity Checks: (none)

Field 2	Name: CompanyName

DataType: String(30)

FieldNo: 2

Validity Checks: (none)

Field 3	Name: LastOrderDate

DataType: Date

FieldNo: 3

Validity Checks: (none)

Field 4	Name: CreditLimit

DataType: BCD(2)

FieldNo: 4

Validity Checks: (none)

Primary Index Key	Fields: CustomerNo

Descending: No

Case-Insensitive: No

Now what we wish to do is restructure the data file so that it looks like the following:

Attribute	New Value

Data File Description	Customer Information

Field 1	Name: CustomerNo

DataType: Integer

FieldNo: 1

Validity Checks: Required (not NULL)

Field 2	Name: ContactName

DataType: String(30)

FieldNo: 5

Validity Checks: (none)

Field 3	Name: CompanyName

DataType: String(30)

FieldNo: 2

Validity Checks: Required (not NULL)

Field 4	Name: LastOrderDate

DataType: Date

FieldNo: 3

Validity Checks: (none)

Field 5	Name: CreditLimit

DataType: BCD(2)

FieldNo: 4

Validity Checks: MinValue (> 0)

Primary Index Key	Fields: CustomerNo

Descending: No

Case-Insensitive: No

Secondary Index Key	Fields: CompanyName

Descending: No

Case-Insensitive: Yes

As you can see, what we want to do is:

 	Add a new field called ContactName after the CustomerNo field

 	Make the existing CustomerNo field be required

 	Make the existing CompanyName field be required

 	Make the existing CreditLimit field be required to be greater than 0

 	Add a new case-insensitive secondary key called CompanyName consisting of the CompanyName field

Please note that field numbers are always 1-based, not 0-based.  This is very important to remember when restructuring data files.

The following code will restructure our example CUSTOMER.DAT data file so that it looks like we want.

with DBISAMTable1 do

  begin

  with RestructureFieldDefs do

    begin

    Clear;

    Add('CustomerNo',ftInteger,0,True,'','','','',1);

    Add('ContactName',ftString,30,False,'','','','',5);

    Add('CompanyName',ftString,30,True,'','','','',2);

    Add('LastOrderDate',ftDate,0,False,'','','','',3);

    Add('CreditLimit',ftBCD,2,False,'','0','','',4);

    end;

  with IndexDefs do

    begin

    Clear;

    Add('','CustomerNo',[ixPrimary]);

    Add('CompanyName','CompanyName'[ixCaseInsensitive]);

    end;

  RestructureTable(False,'','Customer Information');

end;

You can use the OnRestructureProgress event described below to display the progress of the restructure to the user of your application and you can use the OnDataLost event described below to deal with the possibility of data loss during the restructure process.

FlushBuffers Method	This public method is used to flush the data buffers of a data file that has been opened exclusive. This method has no parameters.  Normally a data file opened exclusively only flushes it's buffers to disk when absolutely necessary or when the data file is closed.  Using this method at key points in your application on a data file that has been opened exclusively will help prevent data loss and corruption in the case of an unexpected application termination like a power loss.

TableIsLocked Method	This public method is used to determine if the current data file has been locked using the LockTable method.  This method simply returns True if the current data file is locked, and False if it is not.  Please note, this method only looks at whether the current application has locked the current data file, not if other applications have locked the current data file.

RecordIsLocked Method	This public method is used to determine if the current record in the current data file has been locked using the Edit method.  This method simply returns True if the current record is locked, and False if it is not.  Please note, this method only looks at whether the current application has locked the current record, not if other applications have locked the current record.

InMemory Property	This published Boolean property is used to indicate whether you wish the current data file to be an in-memory data file or a disk-based data file.  Setting this property to True will cause DBISAM to treat the current data file entirely in memory.  DBISAM in-memory data files behave exactly like disk-based data files except for one small difference - you cannot restructure in-memory data files using the RestructureTable method.  You must first create the data file using the CreateTable method and then delete it using the DeleteTable.  What this means is that you cannot open an in-memory data in design mode in the IDE.

The following is an example of using the InMemory property, the CreateTable method, and the DeleteTable method to create an in-memory data file, perform some operations, and then delete the data file:

with DBISAMTable1 do

  begin

  DatabaseName:='';

  TableName:='MEMCUST.DAT';

  InMemory:=True;

  with FieldDefs do

    begin

    Clear;

    Add('CustomerNo',ftInteger,0,True);

    Add('ContactName',ftString,30,False);

    Add('CompanyName',ftString,30,True);

    Add('LastOrderDate',ftDate,0,False);

    Add('CreditLimit',ftBCD,2,False);

    end;

  with IndexDefs do

    begin

    Clear;

    Add('','CustomerNo',[ixPrimary]);

    end;

  CreateTable;

  try

    { Perform some operations on the data file }

  finally

    DeleteTable;

  end;

end;

SaveToStream Method

LoadFromStream Method	These public methods are used to load and save the current in-memory data file to and from a stream (any TStream descendant).  These methods are only valid when dealing with in-memory data files (InMemory property should be True) and will be ignored for disk-based data files.  Please see the sample project MEMBLOB.DPR in the SAMPLES sub-directory under the main DBISAM install directory for an example of using the SaveToStream and LoadFrom Stream methods to implement embedded sub-tables inside of a single record.

OnRepairProgress Event	This published event is used to handle progress notification during a RepairTable method call.  There are three parameters passed to the event:

Event Parameter	Notes

Sender	This TObject parameter will be the current TTable or TDBISAMTable executing the RepairTable method.

CurrentRecord	This Longint parameter indicates the current record being repaired in the data file.

PercentDone	This Word parameter indicates the current percentage of completion for the RepairTable operation.

OnIndexProgress Event	This published event is used to handle progress notification during an AddIndex or DeleteIndex method call.  There are three parameters passed to the event:

Event Parameter	Notes

Sender	This TObject parameter will be the current TTable or TDBISAMTable executing the AddIndex or DeleteIndex method.

CurrentRecord	This Longint parameter indicates the current record being added or deleted from the available indexes in the data file.

PercentDone	This Word parameter indicates the current percentage of completion for the AddIndex or DeleteIndex operation.

OnRestructureProgress Event	This published event is used to handle progress notification during a RestructureTable method call.  There are three parameters passed to the event:

Event Parameter	Notes

Sender	This TObject parameter will be the current TTable or TDBISAMTable executing the RestructureTable method.

CurrentRecord	This Longint parameter indicates the current record being restructured in the data file.

PercentDone	This Word parameter indicates the current percentage of completion for the RestructureTable operation.

 OnDataLost Event	This published event is used to handle data loss during a RestructureTable method call.  There are three parameters passed to the event:

Event Parameter	Notes

Sender	This TObject parameter will be the current TTable or TDBISAMTable executing the RestructureTable method.

Cause	This TDataLossCause parameter indicates the current cause for the potential data loss.  The TDataLossCause parameter can be one of the following:

 dlUnknown

DBISAM cannot determine why data loss is occurring, this should never occur.

 dlKeyViolation

DBISAM has encounterd a key violation due most likely to the modification to the definition of the primary key fields in the current data file.

 dlValidityCheckFail

DBISAM has encountered a validity check (Required, Min/Max) failure due most likely to the addition of a new validity check constraint.

 dlFieldDeletion

DBISAM has encountered data loss due to a field deletion.

 dlFieldConversion

DBISAM has encountered data loss due to an unmanageable field conversion, such as a conversion from a BLOB field to a TimeStamp field.

ContinueRestructure	This variable Boolean parameter can be used to indicate to DBISAM whether the current restructure operation should be continued, even with the data loss, or aborted with the data file returned to it's pre-restructure state.

StopAsking	This variable Boolean parameter can be used to indicate to DBISAM whether it should stop making OnDataLost event calls and ignore and future data loss during the restructure operation.

TransactionsInMemory Property	This published Boolean property is used to determine whether the current data file should process all transactions in an in-memory transaction log or use a disk-based transaction log.  If performance is especially critical during transactions then you should set this property to True.

LockRetryCount Property	This published Byte property is used to determine the number of lock retries attempted when a record or file lock attempt fails.  The default value is 15 retries.  You should increase this figure if your multi-user network is especially busy and you start to receive lock failure exceptions.

LockWaitTime Property	This published Word property is used to determine the amount of time, in milliseconds, between lock retries when a record or file lock attempt fails.  The default value is 100 milliseconds.  You should increase this figure if your multi-user network is especially busy and you start to receive lock failure exceptions.

FilterOptimizeLevel	This public property of type TOptimizeLevel indicates whether the current expression filter specified in the Filter property is either not optimizable (olNone), partially optimizable (olPartial), or fully optimizable (olFull). If the Filter property is empty or the data file is closed this property will contain the value olNone.

Encrypted	This public Boolean property indicates whether the current data file is encrypted or not. If the current data file is closed this property will contain False.

Password	This public string property indicates the password for the current data file if the data file is encrypted.  If the current data file is closed or not encrypted then this property will contain a blank string.


Overview of Delphi 4 Support

DBISAM includes a TDataset descendant component for Delphi 4.  The following is the list of files that make up the Delphi 4 support:

 	DBISAMDB.BPL  (The design-time and run-time package for DBISAM, includes the TDBISAMSession, TDBISAMDatabase, TDBISAMDataset (non-visible component), and TDBISAMTable components)

 	DBISAMTB.DCU  (The compiled unit that contains all of the components in the package)

 	DBISAMRG.DCU (The compiled registration unit for all of the components in the package and their associates property editors)

 	DBISAMMS.DCU (The compiled unit for the master-detail property editor)

 	DBISAMCN.DCU (The compiled unit for all of the constants referenced in the DBISAM interface units)

 Installation

 Differences Between Delphi/BDE and Delphi/DBISAM


Delphi 4 Installation

To install the design-time package (DBISAMDB.BPL) for DBISAM into the component library in Delphi 4, please perform the following steps in Delphi:

1	Select the Component option from the main menu

2	Select the Install Packages option from the Component menu

3	Select the Add button from the Install Packages dialog.  This will bring forward an open file dialog.  In this dialog type in the following name:

<Install Directory>\DELPHI4\DBISAMDB.BPL

Selecting the OK button will then install the design-time package for DBISAM into the Delphi environment.  The DBISAM components will show up on the Data Access tab of the component palette.

Before you can compile any projects using DBISAM you must make sure that the global search path in Delphi 4 includes the path where the DBISAMDB.BPL file is located.

To complete the installation by adding the location of the DBISAM.BPL design-time package to the library search path please perform the following steps in Delphi:

1	Select the Tools option from the main menu

2	Select the Environment Options option from the Tools menu

3	Select the Library Path edit control and move the cursor to the end of the field and type in:

;<Install Directory>\DELPHI4

Please be sure to include the semicolon before the DBISAM path in order to separate it from the rest of the existing library search path.

If you have any problems with this procedure please be sure to contact technical support for help.


Delphi 4 Differences
Differences Between Delphi/BDE and Delphi/DBISAM in Delphi 4

There are several things that are different between the original Delphi TSession, TDatabase, and TTable components and the replacement components TDBISAMSession, TDBISAMDatabase, and TDBISAMTable provided by DBISAM.  The TQuery, TStoredProc, and TBatchMove components have been removed in the DBISAM support for Delphi 4, there are no equivalent components available in DBISAM.  Please also note that in order to use BLOB streams in DBISAM you must use the provided TDBISAMBlobStream object (located in the DBISAMTB.DCU unit) instead of the TBlobStream object used with the BDE. The two are identical in function and only differ only in name.  The differences between the new TDBISAMxxxxxx components and the original BDE components is documented here by component:

 TDBISAMSession Component

 TDBISAMDatabase Component

 TDBISAMTable Component


Delphi 4 TDBISAMSession Component
Differences Between Delphi/BDE and Delphi/DBISAM in Delphi 4

TDBISAMSession Component

The following is a listing of the properties and methods in the TDBISAMSession component that have changed in behavior with DBISAM and the notes about the changes:

Property, Method, or Event	Notes

Locale Property	DBISAM does not currently provide for international support so the Locale property has been removed

NetFileDir Property

PrivateDir Property	Both of these properties are removed in the TDBISAMSession component.  The NetFileDir and PrivateDir properties are based on concepts specifically related to using Paradox data files and the BDE.

TraceFlags Property	The TraceFlags property is removed in the TDBISAMSession component.

SQLHourGlass Property	The SQLHourGlass property is removed in the TDBISAMSession component.

IsAlias Property

ConfigMode Property

AddAlias Method

AddDriver Method

AddStandardAlias Method

DeleteAlias Method

DeleteDriver Method

GetAliasDriverName Method

GetAliasNames Method

GetAliasParams Method

GetConfigParams Method

GetDriverNames Method

GetDriverParams Method

GetStoredProcNames Method

ModifyAlias Method

ModfifyDriver Method

SaveConfigFile Method	These properties and methods have been removed in the TDBISAMSession component.  DBISAM does not support either alias names or stored procedures and only deals with one driver which is the DBISAM database system itself.


Delphi 4 TDBISAMDatabase Component
Differences Between Delphi/BDE and Delphi/DBISAM in Delphi 4

TDBISAMDatabase Component

The following is a listing of the properties and methods in the TDBISAMDatabase component that have changed in behavior with DBISAM and the notes about the changes:

Property, Method, or Event	Notes

Locale Property	DBISAM does not currently provide for international support so the Locale property has been removed.

TransIsolation Property

StartTransaction Method

Commit Method

Rollback Method	DBISAM allows for transactions, and just like the BDE only one per database can be active at any given time.  When you start a transaction using the StartTransaction method of the TDBISAMDatabase component, any TDBISAMTable components that are connected to this TDBISAMDatabase component are now involved in the current transaction.  Any changes made to these TDBISAMTable components will be logged in the appropriate transaction log and will be committed or rolled back as a group under the current transaction. You must be very careful when using multiple TDBISAMDatabase components with active transactions on the same TDBISAMTable components, since either rolling back any changes or committing any changes could cause great confusion as to how the data files actually got into their current state.  It is normally only a good idea to have one active transaction on any given TDBISAMTable component and to make sure that your TDBISAMTable components are not accidentally attached to different databases.  Also, if you do not explicitly use a TDBISAMDatabase component and instead rely on the temporary TDBISAMDatabase component ( this TDBISAMDatabase component is created for TDBISAMTable components that use a path name for the DatabaseName property), be sure to remember that all TDBISAMTable components in the current application will be attached to the same temporary database.

DBISAM only supports "dirty read" transactions so the TransIsolation property of the TDBISAMDatabase has been removed.

Finally, the default Delphi TDatabase component does not ensure that the TTable components involved in the current transaction are all in the dsBrowse state, or, in other words, not editing, adding, filtering, or searching, when it commits or rolls back an existing transaction.  In the DBISAM replacement TDatabase component all TTable components are forced into browse mode before any transaction is rolled back or committed.  This means that any records being edited, added, or searched on will be posted using the standard Post method of TTable component if the transaction is being committed and cancelled if the transaction is being rolled back.

Params Property

Directory Property	The Params property has been removed and it's functionality for specifying the path for a TDBISAMDatabase component has been replaced with the Directory property.  This property specifies which directory the database will use for opening up data files for use as TDBISAMTable components.

AliasName Property	DBISAM does not support aliases so the AliasName property has been removed.

DriverName Property	DBISAM only supports one driver, the DBISAM Database System, so this property has been removed.

LoginPrompt Property

OnLogin Event	User names and logging in are not necessary when using DBISAM so the LoginPrompt property and the OnLogin event have been removed.

SessionAlias Property	DBISAM does not support aliases so the SessionAlias property has been removed.

TraceFlags Property	The TraceFlags property has been removed.

ApplyUpdates Method	DBISAM does not support Cached Updates so the ApplyUpdates method has been removed.

FlushSchemaCache Method	DBISAM does not cache any schema information for data files, so the FlushSchemaCache method has been removed.


Delphi 4 TDBISAMTable Component
Differences Between Delphi/BDE and Delphi/DBISAM in Delphi 4

TDBISAMTable Component

The following is a listing of the properties and methods in the TDBISAMTable component that have changed in behavior with DBISAM and the notes about the changes:

Property, Method, or Event	Notes

Locale Property

DBLocale Property	DBISAM does not currently provide for international support so the Locale and DBLocale properties have been removed.

KeyExclusive Property	DBISAM does not support exclusive keys in ranges and searches so the KeyExclusive property has been removed.

TableLevel Property	DBISAM does not support different table levels, or versions, currently so the TableLevel property has been removed.

TableType Property	There is only one table type for DBISAM so this property has been removed.

LockTable Method

UnlockTable Method	DBISAM only supports locking an entire to prevent other users from writing to the table, not reading the table, so the LockTable and UnlockTable methods do not accept a parameter indicating the type of lock (ltRead or ltWrite) like the default Delphi TTable component does.

BatchMove Method	Batch moves (and the TBatchMove component) are not currently supported in DBISAM so the BatchMove method has been removed.

CreateTable Method

AddIndex Method	There are several differences between how creating tables using the CreateTable method is handled in the default Delphi TTable component and the BDE versus how it is handled in the TDBISAMTable component.

When adding field definitions for blob fields such as memos or graphics, Paradox and the BDE allow you to specify a field size that indicates how much of the current blob field contents should be stored directly in the data record.  DBISAM does not support this feature, so the field size for blob fields should always be set to 0 as indicated in the following example:

with DBISAMTable1 do

  begin

  Active := False;

  DatabaseName := 'Delphi_Demos';

  TableName := 'CustInfo';

  with FieldDefs do

    begin

    Clear;

    Add('Field1', ftInteger, 0, True);

    Add('Field2', ftMemo, 0, False);  { <--- With DBISAM tables the field size must be 0 for blob fields }

    end;

  with IndexDefs do

    begin

    Clear;

    Add('', 'Field1', [ixPrimary]);

    end;

  CreateTable;

  end;

The following TField components are considered blob fields:

 	TMemoField

TGraphicField

TBlobField

There are some options used when adding index definitions used in the CreateTable method, and also when using the AddIndex method, that are handled differently than the default Delphi TTable component.

Option	Notes

ixUnique 	This option is used with the BDE and Paradox and dBase tables to specify a unique index. In DBISAM the unique option behaves in the same manner as Paradox.  The unique option enforces that duplicate index keys for the specified index will not be allowed in the data file.  The uniqueness of index keys are enforced automatically for primary indexes (defined using the ixPrimary option alone).

ixCaseInsensitive	DBISAM does support case-insensitive indexes and the ixCaseInsensitive option for both primary and secondary indexes.

ixNonMaintained	This option is used with the BDE and Paradox tables to specify indexes that are not maintained automatically by the BDE when updating the table.  DBISAM does not support this feature so this option is ignored.

ixDescending	DBISAM does support descending indexes and the ixDescending option for both primary and secondary indexes.  An example of using the CreateTable to create a table using both primary and secondary indexes, ascending and descending is as follows:

with DBISAMTable1 do

  begin

  Active := False;

  DatabaseName := 'Delphi_Demos';

  TableName := 'CustInfo';

  with FieldDefs do

    begin

    Clear;

    Add('Field1', ftInteger, 0, True);

    Add('Field2', ftString, 20, False);

    Add('Field3', ftDate, 0, False);

    end;

  with IndexDefs do

    begin

    Clear;

    Add('', 'Field1', [ixPrimary]); {<-- This is an ascending primary index, you could add the ixDescending option if you wanted to make this primary index descending }

    Add('Field2Index', 'Field2', []);  {<-- This index definition is an ascending secondary index }

    Add('Field3Index', 'Field3', [ixDescending]);  {<-- This index definition is a descending secondary index }

    end;

  CreateTable;

  end;

CachedUpdates Property

UpdateObject Property

UpdateStatus Property

UpdateRecordTypes Property

UpdatesPending Property

ApplyUpdates Method

CancelUpdates Method

CommitUpdates Method

RevertRecord Method

OnUpdateError Event

OnUpdateRecord Event	DBISAM does not support cached updates, so the properties, methods, and events listed have been removed.

ExpIndex Property	DBISAM does not support expressions in indexes so the ExpIndex property has been removed.

Constraints Property

ConstraintCallback Method

ConstraintsDisabled Method

DisableContraints Method

EnableConstraints Method	DBISAM does not support constraints so theses properties and methods have been removed.

IndexFiles Property

OpenIndexFile Method

CloseIndexFile Method	DBISAM does not support specifying an external index file for use with a TTable so the properties and methods listed have been removed.

OnServerYield Event	DBISAM is not a client-server database system so the OnServerYield event has been removed.

RestructureFieldDefs Property	This public runtime property, which is of the type TRestructureFieldDefs, is used to define data file restructure parameters for individual fields.  This property is very similar to the normal TTable FieldDefs property, the only difference in it's usage is that each TRestructureFieldDef object contained in the RestructureFieldDefs list contains different properties that specify instructions on how to restructure a data file's field definitions.  The following is the list of properties in each TRestructureFieldDef and their meaning:

Property	Notes

DataType	The DataType property is of the type TFieldType and is used to indicate the data type for the field.  Please see the Delphi help for more information on the TFieldType type.

FieldNo	The FieldNo property is of the type Integer and is used to indicate the field position in the restructure process.  This property is very important as you will see later in the example restructure code.  Please note that the FieldNo property is 1-based, not 0-based, just like the normal FieldNo property.

Name	The Name property is of the type String and is used to indicate the field name.

Required	The Required property is of the type Boolean and is used to indicate whether a field is required (cannot be NULL) or not.

Size	The Size property is of the type Word and is used to indicate the size of the field.  This property will only be not equal to 0 for string fields, byte fields, and BCD fields.

DefaultValue	The DefaultValue property is of the type String and is used to indicate the default value for the field. The default value provided in this property must be appropriate for the data type of the field.

Description	The Description property is of the type String and is used to indicate the description of the field.

MinValue	The MinValue property is of the type String and is used to indicate the minimum value allowed for the field. The minimum value provided in this property must be appropriate for the data type of the field.

MaxValue	The MaxValue property is of the type String and is used to indicate the maximum value allowed for the field. The maximum value provided in this property must be appropriate for the data type of the field.

Please see the RestructureTable method below for an example on using the RestructureFieldDefs property when restructuring a data file.

Description Property	This public runtime property is of the type String and indicates the description of the current data file.  This property is read-only, you must restructure a data file in order to change it's description.

LastUpdated Property	This public runtime property is of the type TDateTime and indicates the last time the current data file was updated.  This property is read-only is automatically maintained by DBISAM for each data file.

CopyTable Method	This public method is used to copy an existing data file to a new data file.  This method accepts one parameter - the name of the data file to copy to.  The following is an example of using the CopyTable method to copy a data file:

with DBISAMTable1 do

  begin

  Active:=False;

  DatabaseName:='C:\MYDATA';

  TableName:='CUSTOMER.DAT';

  CopyTable('C:\MYDATA\BACKUP\CUSTOMER.DAT');

  end;

RepairTable Method	This public method is used to repair an existing data file that has been corrupted.  This method has no parameters.  The following is an example of using the RepairTable method to repair a data file:

with DBISAMTable1 do

  begin

  Active:=False;

  DatabaseName:='C:\MYDATA';

  TableName:='CUSTOMER.DAT';

  RepairTable;

  end;

You can use the OnRepairProgress event described below to display the progress of the repair to the user of your application.

RestructureTable Method	This public method is used to restructure an existing data file. This method accepts four parameters:

Parameter	Notes

NewEncrypted

(Boolean)	The new encrypted flag, if True then the data file will be encrypted, if False then the data file will not be encrypted.

NewPassword

(String)	The new password string, this only applies if the NewEncrypted parameter is True.  If the NewEncrypted parameters if False then this parameter will be ignored. The password string cannot be blank and cannot be more than 15 characters in length.

NewDescription

(String)	The new description of the data file to being restructured.

NewBlobBlockSize

(Word)	The new BLOB block size of the data file to being restructured.  This value may be between 64 bytes and 64k (65535 bytes).

The following is an example of using the RestructureFieldDefs property, the RestructureTable method, and the OnRestructureProgress and OnDataLost events (all found only in the TDBISAMTable component) to restructure a data file in code.

For this example we'll assume an existing data file called CUSTOMER.DAT that contains the following structure:

Attribute	Current Value

Data File Description	(blank)

Field 1	Name: CustomerNo

DataType: Integer

FieldNo: 1

Validity Checks: (none)

Field 2	Name: CompanyName

DataType: String(30)

FieldNo: 2

Validity Checks: (none)

Field 3	Name: LastOrderDate

DataType: Date

FieldNo: 3

Validity Checks: (none)

Field 4	Name: CreditLimit

DataType: BCD(2)

FieldNo: 4

Validity Checks: (none)

Primary Index	Fields: CustomerNo

Descending: No

Case-Insensitive: No

Now what we wish to do is restructure the data file so that it looks like the following:

Attribute	New Value

Data File Description	Customer Information

Field 1	Name: CustomerNo

DataType: Integer

FieldNo: 1

Validity Checks: Required (not NULL)

Field 2	Name: ContactName

DataType: String(30)

FieldNo: 5

Validity Checks: (none)

Field 3	Name: CompanyName

DataType: String(30)

FieldNo: 2

Validity Checks: Required (not NULL)

Field 4	Name: LastOrderDate

DataType: Date

FieldNo: 3

Validity Checks: (none)

Field 5	Name: CreditLimit

DataType: BCD(2)

FieldNo: 4

Validity Checks: MinValue (> 0)

Primary Index	Fields: CustomerNo

Descending: No

Case-Insensitive: No

Secondary Index	Fields: CompanyName

Descending: No

Case-Insensitive: Yes

As you can see, what we want to do is:

 	Add a new field called ContactName after the CustomerNo field

 	Make the existing CustomerNo field be required

 	Make the existing CompanyName field be required

 	Make the existing CreditLimit field be required to be greater than 0

 	Add a new case-insensitive secondary index called CompanyName consisting of the CompanyName field

Please note that field numbers are always 1-based, not 0-based.  This is very important to remember when restructuring data files.

The following code will restructure our example CUSTOMER.DAT data file so that it looks like we want.

with DBISAMTable1 do

  begin

  with RestructureFieldDefs do

    begin

    Clear;

    Add('CustomerNo',ftInteger,0,True,'','','','',1);

    Add('ContactName',ftString,30,False,'','','','',5);

    Add('CompanyName',ftString,30,True,'','','','',2);

    Add('LastOrderDate',ftDate,0,False,'','','','',3);

    Add('CreditLimit',ftBCD,2,False,'','0','','',4);

    end;

  with IndexDefs do

    begin

    Clear;

    Add('','CustomerNo',[ixPrimary]);

    Add('CompanyName','CompanyName'[ixCaseInsensitive]);

    end;

  RestructureTable(False,'','Customer Information',512);

end;

You can use the OnRestructureProgress event described below to display the progress of the restructure to the user of your application and you can use the OnDataLost event described below to deal with the possibility of data loss during the restructure process.

FlushBuffers Method	This public method is used to flush the data buffers of a data file that has been opened exclusively. This method has no parameters.  Normally a data file opened exclusively only flushes it's buffers to disk when absolutely necessary or when the data file is closed.  Using this method at key points in your application on a data file that has been opened exclusively will help prevent data loss and corruption in the case of an unexpected application termination like a power loss.

TableIsLocked Method	This public method is used to determine if the current data file has been locked using the LockTable method.  This method simply returns True if the current data file is locked, and False if it is not.  Please note, this method only looks at whether the current application has locked the current data file, not if other applications have locked the current data file.

RecordIsLocked Method	This public method is used to determine if the current record in the current data file has been locked using the Edit method.  This method simply returns True if the current record is locked, and False if it is not.  Please note, this method only looks at whether the current application has locked the current record, not if other applications have locked the current record.

InMemory Property	This published Boolean property is used to indicate whether you wish the current data file to be an in-memory data file or a disk-based data file.  Setting this property to True will cause DBISAM to treat the current data file entirely in memory.  DBISAM in-memory data files behave exactly like disk-based data files except for one small difference - you cannot place locks on in-memory data files or the records contained in them.  You must first create the data file using the CreateTable method and then delete it using the DeleteTable.  What this means is that you cannot open an in-memory data in design mode in the IDE.

The following is an example of using the InMemory property, the CreateTable method, and the DeleteTable method to create an in-memory data file, perform some operations, and then delete the data file:

with DBISAMTable1 do

  begin

  DatabaseName:='';

  TableName:='MEMCUST.DAT';

  InMemory:=True;

  with FieldDefs do

    begin

    Clear;

    Add('CustomerNo',ftInteger,0,True);

    Add('ContactName',ftString,30,False);

    Add('CompanyName',ftString,30,True);

    Add('LastOrderDate',ftDate,0,False);

    Add('CreditLimit',ftBCD,2,False);

    end;

  with IndexDefs do

    begin

    Clear;

    Add('','CustomerNo',[ixPrimary]);

    end;

  CreateTable;

  try

    { Perform some operations on the data file }

  finally

    DeleteTable;

  end;

end;

SaveToStream Method

LoadFromStream Method	These public methods are used to load and save the current in-memory data file to and from a stream (any TStream descendant).  These methods are only valid when dealing with in-memory data files (InMemory property should be True) and will be ignored for disk-based data files.  Please see the sample project MEMBLOB.DPR in the SAMPLES sub-directory under the main DBISAM install directory for an example of using the SaveToStream and LoadFrom Stream methods to implement embedded sub-tables inside of a single record.

OnRepairProgress Event	This published event is used to handle progress notification during a RepairTable method call.  There are three parameters passed to the event:

Event Parameter	Notes

Sender	This TObject parameter will be the current TTable or TDBISAMTable executing the RepairTable method.

CurrentRecord	This Longint parameter indicates the current record being repaired in the data file.

PercentDone	This Word parameter indicates the current percentage of completion for the RepairTable operation.

OnIndexProgress Event	This published event is used to handle progress notification during an AddIndex or DeleteIndex method call.  There are three parameters passed to the event:

Event Parameter	Notes

Sender	This TObject parameter will be the current TTable or TDBISAMTable executing the AddIndex or DeleteIndex method.

CurrentRecord	This Longint parameter indicates the current record being added or deleted from the available indexes in the data file.

PercentDone	This Word parameter indicates the current percentage of completion for the AddIndex or DeleteIndex operation.

OnRestructureProgress Event	This published event is used to handle progress notification during a RestructureTable method call.  There are three parameters passed to the event:

Event Parameter	Notes

Sender	This TObject parameter will be the current TTable or TDBISAMTable executing the RestructureTable method.

CurrentRecord	This Longint parameter indicates the current record being restructured in the data file.

PercentDone	This Word parameter indicates the current percentage of completion for the RestructureTable operation.

 OnDataLost Event	This published event is used to handle data loss during a RestructureTable method call.  There are three parameters passed to the event:

Event Parameter	Notes

Sender	This TObject parameter will be the current TTable or TDBISAMTable executing the RestructureTable method.

Cause	This TDataLossCause parameter indicates the current cause for the potential data loss.  The TDataLossCause parameter can be one of the following:

 dlUnknown

DBISAM cannot determine why data loss is occurring, this should never occur.

 dlKeyViolation

DBISAM has encounterd a key violation due most likely to a modification to the definition of the primary index fields in the current data file.

 dlValidityCheckFail

DBISAM has encountered a validity check (Required, Min/Max) failure due most likely to the addition of a new validity check constraint.

 dlFieldDeletion

DBISAM has encountered data loss due to a field deletion.

 dlFieldConversion

DBISAM has encountered data loss due to an unmanageable field conversion, such as a conversion from a BLOB field to a TimeStamp field.

ContinueRestructure	This variable Boolean parameter can be used to indicate to DBISAM whether the current restructure operation should be continued, even with the data loss, or aborted with the data file returned to it's pre-restructure state.

StopAsking	This variable Boolean parameter can be used to indicate to DBISAM whether it should stop making OnDataLost event calls and ignore any future data loss during the restructure operation.

TransactionsInMemory Property	This published Boolean property is used to determine whether the current data file should process all transactions in an in-memory transaction log or use a disk-based transaction log.  If performance is especially critical during transactions then you should set this property to True.

LockRetryCount Property	This published Byte property is used to determine the number of lock retries attempted when a record or file lock attempt fails.  The default value is 15 retries.  You should increase this figure if your multi-user network is especially busy and you start to receive lock failure exceptions.

LockWaitTime Property	This published Word property is used to determine the amount of time, in milliseconds, between lock retries when a record or file lock attempt fails.  The default value is 100 milliseconds.  You should increase this figure if your multi-user network is especially busy and you start to receive lock failure exceptions.

FilterOptimizeLevel	This public property of type TOptimizeLevel indicates whether the current expression filter specified in the Filter property is either not optimizable (olNone), partially optimizable (olPartial), or fully optimizable (olFull). If the Filter property is empty or the data file is closed this property will contain the value olNone.

Encrypted	This public Boolean property indicates whether the current data file is encrypted or not. If the current data file is closed this property will contain False.

Password	This public string property indicates the password for the current data file if the data file is encrypted.  If the current data file is closed or not encrypted then this property will contain a blank string.